^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/alpha/kernel/setup.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1995 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /* 2.3.x bootmem, 1999 Andrea Arcangeli <andrea@suse.de> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Bootup setup stuff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/screen_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mc146818rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/root_dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/initrd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/eisa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/pfn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/sysrq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) extern struct atomic_notifier_head panic_notifier_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static struct notifier_block alpha_panic_block = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) alpha_panic_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) INT_MAX /* try to do it first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <asm/hwrpb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <asm/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "proto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include "pci_impl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct hwrpb_struct *hwrpb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) EXPORT_SYMBOL(hwrpb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long srm_hae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int alpha_l1i_cacheshape;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int alpha_l1d_cacheshape;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int alpha_l2_cacheshape;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int alpha_l3_cacheshape;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #ifdef CONFIG_VERBOSE_MCHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* 0=minimum, 1=verbose, 2=all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* These can be overridden via the command line, ie "verbose_mcheck=2") */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned long alpha_verbose_mcheck = CONFIG_VERBOSE_MCHECK_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct cpumask node_to_cpumask_map[MAX_NUMNODES] __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) EXPORT_SYMBOL(node_to_cpumask_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Which processor we booted from. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int boot_cpuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Using SRM callbacks for initial console output. This works from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * setup_arch() time through the end of time_init(), as those places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * are under our (Alpha) control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * "srmcons" specified in the boot command arguments allows us to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * see kernel messages during the period of time before the true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * console device is "registered" during console_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * As of this version (2.5.59), console_init() will call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * disable_early_printk() as the last action before initializing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * the console drivers. That's the last possible time srmcons can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * unregistered without interfering with console behavior.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * By default, OFF; set it with a bootcommand arg of "srmcons" or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * "console=srm". The meaning of these two args is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * "srmcons" - early callback prints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * "console=srm" - full callback based console, including early prints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int srmcons_output = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Enforce a memory size limit; useful for testing. By default, none. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned long mem_size_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Set AGP GART window size (0 means disabled). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #ifdef CONFIG_ALPHA_GENERIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct alpha_machine_vector alpha_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) EXPORT_SYMBOL(alpha_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #ifndef alpha_using_srm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int alpha_using_srm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) EXPORT_SYMBOL(alpha_using_srm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #ifndef alpha_using_qemu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int alpha_using_qemu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static struct alpha_machine_vector *get_sysvec_byname(const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void get_sysnames(unsigned long, unsigned long, unsigned long,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) char **, char **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static void determine_cpu_caches (unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static char __initdata command_line[COMMAND_LINE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * The format of "screen_info" is strange, and due to early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * i386-setup code. This is just enough to make the console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * code think we're on a VGA color display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct screen_info screen_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .orig_x = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .orig_y = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .orig_video_cols = 80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .orig_video_lines = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .orig_video_isVGA = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .orig_video_points = 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) EXPORT_SYMBOL(screen_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * The direct map I/O window, if any. This should be the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * for all busses, since it's used by virt_to_bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned long __direct_map_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned long __direct_map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) EXPORT_SYMBOL(__direct_map_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) EXPORT_SYMBOL(__direct_map_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Declare all of the machine vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* GCC 2.7.2 (on alpha at least) is lame. It does not support either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) __attribute__((weak)) or #pragma weak. Bypass it and talk directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) to the assembler. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define WEAK(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) extern struct alpha_machine_vector X; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) asm(".weak "#X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) WEAK(alcor_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) WEAK(alphabook1_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) WEAK(avanti_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) WEAK(cabriolet_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) WEAK(clipper_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) WEAK(dp264_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) WEAK(eb164_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) WEAK(eb64p_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) WEAK(eb66_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) WEAK(eb66p_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) WEAK(eiger_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) WEAK(jensen_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) WEAK(lx164_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) WEAK(lynx_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) WEAK(marvel_ev7_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) WEAK(miata_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) WEAK(mikasa_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) WEAK(mikasa_primo_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) WEAK(monet_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) WEAK(nautilus_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) WEAK(noname_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) WEAK(noritake_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) WEAK(noritake_primo_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) WEAK(p2k_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) WEAK(pc164_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) WEAK(privateer_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) WEAK(rawhide_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) WEAK(ruffian_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) WEAK(rx164_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) WEAK(sable_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) WEAK(sable_gamma_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) WEAK(shark_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) WEAK(sx164_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) WEAK(takara_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) WEAK(titan_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) WEAK(webbrick_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) WEAK(wildfire_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) WEAK(xl_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) WEAK(xlt_mv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #undef WEAK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * I/O resources inherited from PeeCees. Except for perhaps the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * turbochannel alphas, everyone has these on some sort of SuperIO chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * ??? If this becomes less standard, move the struct out into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * machine vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) reserve_std_resources(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static struct resource standard_io_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { .name = "rtc", .start = -1, .end = -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { .name = "dma1", .start = 0x00, .end = 0x1f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { .name = "pic1", .start = 0x20, .end = 0x3f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) { .name = "timer", .start = 0x40, .end = 0x5f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { .name = "keyboard", .start = 0x60, .end = 0x6f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) { .name = "dma page reg", .start = 0x80, .end = 0x8f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) { .name = "pic2", .start = 0xa0, .end = 0xbf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) { .name = "dma2", .start = 0xc0, .end = 0xdf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct resource *io = &ioport_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (hose_head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct pci_controller *hose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) for (hose = hose_head; hose; hose = hose->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (hose->index == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) io = hose->io_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* Fix up for the Jensen's queer RTC placement. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) standard_io_resources[0].start = RTC_PORT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) standard_io_resources[0].end = RTC_PORT(0) + 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) for (i = 0; i < ARRAY_SIZE(standard_io_resources); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) request_resource(io, standard_io_resources+i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define PFN_MAX PFN_DOWN(0x80000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define for_each_mem_cluster(memdesc, _cluster, i) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) for ((_cluster) = (memdesc)->cluster, (i) = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) (i) < (memdesc)->numclusters; (i)++, (_cluster)++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static unsigned long __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) get_mem_size_limit(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned long end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) char *from = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) end = simple_strtoul(from, &from, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if ( *from == 'K' || *from == 'k' ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) end = end << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) from++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) } else if ( *from == 'M' || *from == 'm' ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) end = end << 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) from++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } else if ( *from == 'G' || *from == 'g' ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) end = end << 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) from++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return end >> PAGE_SHIFT; /* Return the PFN of the limit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #ifdef CONFIG_BLK_DEV_INITRD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) void * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) move_initrd(unsigned long mem_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) void *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) size = initrd_end - initrd_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) start = memblock_alloc(PAGE_ALIGN(size), PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (!start || __pa(start) + size > mem_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) initrd_start = initrd_end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) memmove(start, (void *)initrd_start, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) initrd_start = (unsigned long)start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) initrd_end = initrd_start + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) printk("initrd moved to %p\n", start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) #ifndef CONFIG_DISCONTIGMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) setup_memory(void *kernel_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct memclust_struct * cluster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct memdesc_struct * memdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned long kernel_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Find free clusters, and init and free the bootmem accordingly. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) memdesc = (struct memdesc_struct *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) (hwrpb->mddt_offset + (unsigned long) hwrpb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) for_each_mem_cluster(memdesc, cluster, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned long end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) printk("memcluster %lu, usage %01lx, start %8lu, end %8lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) i, cluster->usage, cluster->start_pfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cluster->start_pfn + cluster->numpages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) end = cluster->start_pfn + cluster->numpages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (end > max_low_pfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) max_low_pfn = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) memblock_add(PFN_PHYS(cluster->start_pfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) cluster->numpages << PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* Bit 0 is console/PALcode reserved. Bit 1 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) non-volatile memory -- we might want to mark
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) this for later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (cluster->usage & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) memblock_reserve(PFN_PHYS(cluster->start_pfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) cluster->numpages << PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Except for the NUMA systems (wildfire, marvel) all of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * Alpha systems we run on support 32GB of memory or less.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * Since the NUMA systems introduce large holes in memory addressing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * we can get into a situation where there is not enough contiguous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * memory for the memory map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * Limit memory to the first 32GB to limit the NUMA systems to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * memory on their first node (wildfire) or 2 (marvel) to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * not being able to produce the memory map. In order to access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * all of the memory on the NUMA systems, build with discontiguous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * memory support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * If the user specified a memory limit, let that memory limit stand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!mem_size_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) mem_size_limit = (32ul * 1024 * 1024 * 1024) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (mem_size_limit && max_low_pfn >= mem_size_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) printk("setup: forcing memory size to %ldK (from %ldK).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mem_size_limit << (PAGE_SHIFT - 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) max_low_pfn << (PAGE_SHIFT - 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) max_low_pfn = mem_size_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Reserve the kernel memory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) kernel_size = virt_to_phys(kernel_end) - KERNEL_START_PHYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) memblock_reserve(KERNEL_START_PHYS, kernel_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #ifdef CONFIG_BLK_DEV_INITRD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) initrd_start = INITRD_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (initrd_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) initrd_end = initrd_start+INITRD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) (void *) initrd_start, INITRD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!move_initrd(PFN_PHYS(max_low_pfn)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) printk("initrd extends beyond end of memory "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) "(0x%08lx > 0x%p)\ndisabling initrd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) initrd_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) phys_to_virt(PFN_PHYS(max_low_pfn)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) memblock_reserve(virt_to_phys((void *)initrd_start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) INITRD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #endif /* CONFIG_BLK_DEV_INITRD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) extern void setup_memory(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) #endif /* !CONFIG_DISCONTIGMEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) page_is_ram(unsigned long pfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct memclust_struct * cluster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct memdesc_struct * memdesc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) memdesc = (struct memdesc_struct *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) (hwrpb->mddt_offset + (unsigned long) hwrpb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) for_each_mem_cluster(memdesc, cluster, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (pfn >= cluster->start_pfn &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) pfn < cluster->start_pfn + cluster->numpages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return (cluster->usage & 3) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) register_cpus(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) register_cpu(p, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) arch_initcall(register_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void sysrq_reboot_handler(int unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) machine_halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static const struct sysrq_key_op srm_sysrq_reboot_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .handler = sysrq_reboot_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .help_msg = "reboot(b)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .action_msg = "Resetting",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .enable_mask = SYSRQ_ENABLE_BOOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) setup_arch(char **cmdline_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) extern char _end[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct alpha_machine_vector *vec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct percpu_struct *cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) char *type_name, *var_name, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) void *kernel_end = _end; /* end of kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) char *args = command_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) boot_cpuid = hard_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Pre-process the system type to make sure it will be valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * This may restore real CABRIO and EB66+ family names, ie
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * EB64+ and EB66.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * Oh, and "white box" AS800 (aka DIGITAL Server 3000 series)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * and AS1200 (DIGITAL Server 5000 series) have the type as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * the negative of the real one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if ((long)hwrpb->sys_type < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) hwrpb->sys_type = -((long)hwrpb->sys_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) hwrpb_update_checksum(hwrpb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* Register a call for panic conditions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) atomic_notifier_chain_register(&panic_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) &alpha_panic_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) #ifndef alpha_using_srm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* Assume that we've booted from SRM if we haven't booted from MILO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) Detect the later by looking for "MILO" in the system serial nr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) alpha_using_srm = !str_has_prefix((const char *)hwrpb->ssn, "MILO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) #ifndef alpha_using_qemu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Similarly, look for QEMU. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) alpha_using_qemu = strstr((const char *)hwrpb->ssn, "QEMU") != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* If we are using SRM, we want to allow callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) as early as possible, so do this NOW, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) they should work immediately thereafter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) kernel_end = callback_init(kernel_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * Locate the command line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* Hack for Jensen... since we're restricted to 8 or 16 chars for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) boot flags depending on the boot mode, we need some shorthand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) This should do for installation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (strcmp(COMMAND_LINE, "INSTALL") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) strlcpy(command_line, "root=/dev/fd0 load_ramdisk=1", sizeof command_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) strlcpy(command_line, COMMAND_LINE, sizeof command_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) strcpy(boot_command_line, command_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *cmdline_p = command_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * Process command-line arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) while ((p = strsep(&args, " \t")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!*p) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (strncmp(p, "alpha_mv=", 9) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) vec = get_sysvec_byname(p+9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (strncmp(p, "cycle=", 6) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) est_cycle_freq = simple_strtol(p+6, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (strncmp(p, "mem=", 4) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) mem_size_limit = get_mem_size_limit(p+4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (strncmp(p, "srmcons", 7) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) srmcons_output |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (strncmp(p, "console=srm", 11) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) srmcons_output |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (strncmp(p, "gartsize=", 9) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) alpha_agpgart_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) get_mem_size_limit(p+9) << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #ifdef CONFIG_VERBOSE_MCHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (strncmp(p, "verbose_mcheck=", 15) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) alpha_verbose_mcheck = simple_strtol(p+15, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Replace the command line, now that we've killed it with strsep. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) strcpy(command_line, boot_command_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* If we want SRM console printk echoing early, do it now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (alpha_using_srm && srmcons_output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) register_srm_console();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * If "console=srm" was specified, clear the srmcons_output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * flag now so that time.c won't unregister_srm_console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (srmcons_output & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) srmcons_output = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* If we're using SRM, make sysrq-b halt back to the prom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) not auto-reboot. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (alpha_using_srm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) unregister_sysrq_key('b', __sysrq_reboot_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) register_sysrq_key('b', &srm_sysrq_reboot_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * Identify and reconfigure for the current system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) cpu->type, &type_name, &var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (*var_name == '0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) var_name = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!vec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) cpu->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!vec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) panic("Unsupported system type: %s%s%s (%ld %ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) type_name, (*var_name ? " variation " : ""), var_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) hwrpb->sys_type, hwrpb->sys_variation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (vec != &alpha_mv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) alpha_mv = *vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) printk("Booting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #ifdef CONFIG_ALPHA_GENERIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) "GENERIC "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) "on %s%s%s using machine vector %s from %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) type_name, (*var_name ? " variation " : ""),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) var_name, alpha_mv.vector_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) (alpha_using_srm ? "SRM" : "MILO"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) printk("Major Options: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) "SMP "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) #ifdef CONFIG_ALPHA_EV56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) "EV56 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) #ifdef CONFIG_ALPHA_EV67
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) "EV67 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) "LEGACY_START "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) #ifdef CONFIG_VERBOSE_MCHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) "VERBOSE_MCHECK "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) #ifdef CONFIG_DISCONTIGMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) "DISCONTIGMEM "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) "NUMA "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) #ifdef CONFIG_DEBUG_SPINLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) "DEBUG_SPINLOCK "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) #ifdef CONFIG_MAGIC_SYSRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) "MAGIC_SYSRQ "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) printk("Command line: %s\n", command_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * Sync up the HAE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * Save the SRM's current value for restoration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) srm_hae = *alpha_mv.hae_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) __set_hae(alpha_mv.hae_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* Reset enable correctable error reports. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) wrmces(0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Find our memory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) setup_memory(kernel_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) memblock_set_bottom_up(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* First guess at cpu cache sizes. Do this before init_arch. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) determine_cpu_caches(cpu->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* Initialize the machine. Usually has to do with setting up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) DMA windows and the like. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (alpha_mv.init_arch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) alpha_mv.init_arch();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* Reserve standard resources. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) reserve_std_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * Give us a default console. TGA users will see nothing until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * chr_dev_init is called, rather late in the boot sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef CONFIG_VT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) #if defined(CONFIG_VGA_CONSOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) conswitchp = &vga_con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* Default root filesystem to sda2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ROOT_DEV = Root_SDA2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* FIXME: only set this when we actually have EISA in this box? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) EISA_bus = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * Check ASN in HWRPB for validity, report if bad.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * FIXME: how was this failing? Should we trust it instead,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * and copy the value into alpha_mv.max_asn?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (hwrpb->max_asn != MAX_ASN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->max_asn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Identify the flock of penguins.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) setup_smp();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) paging_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static char sys_unknown[] = "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static char systype_names[][16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) "0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) "ADU", "Cobra", "Ruby", "Flamingo", "Mannequin", "Jensen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) "Pelican", "Morgan", "Sable", "Medulla", "Noname",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) "Turbolaser", "Avanti", "Mustang", "Alcor", "Tradewind",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) "Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) "Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) "Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) "Tsunami", "Wildfire", "CUSCO", "Eiger", "Titan", "Marvel"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static char unofficial_names[][8] = {"100", "Ruffian"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static char api_names[][16] = {"200", "Nautilus"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static char eb164_names[][8] = {"EB164", "PC164", "LX164", "SX164", "RX164"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static char alcor_names[][16] = {"Alcor", "Maverick", "Bret"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static int alcor_indices[] = {0,0,0,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static char eb64p_names[][16] = {"EB64+", "Cabriolet", "AlphaPCI64"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static int eb64p_indices[] = {0,0,1,2};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static char eb66_names[][8] = {"EB66", "EB66+"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static int eb66_indices[] = {0,0,1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static char marvel_names[][16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) "Marvel/EV7"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static int marvel_indices[] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static char rawhide_names[][16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) "Dodge", "Wrangler", "Durango", "Tincup", "DaVinci"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static char titan_names[][16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) "DEFAULT", "Privateer", "Falcon", "Granite"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int titan_indices[] = {0,1,2,2,3};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static char tsunami_names[][16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) "0", "DP264", "Warhol", "Windjammer", "Monet", "Clipper",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) "Goldrush", "Webbrick", "Catamaran", "Brisbane", "Melbourne",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) "Flying Clipper", "Shark"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8,9,10,11,12};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static struct alpha_machine_vector * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static struct alpha_machine_vector *systype_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) NULL, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) NULL, /* ADU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) NULL, /* Cobra */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) NULL, /* Ruby */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) NULL, /* Flamingo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) NULL, /* Mannequin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) &jensen_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) NULL, /* Pelican */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) NULL, /* Morgan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) NULL, /* Sable -- see below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) NULL, /* Medulla */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) &noname_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) NULL, /* Turbolaser */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) &avanti_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) NULL, /* Mustang */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) NULL, /* Alcor, Bret, Maverick. HWRPB inaccurate? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) NULL, /* Tradewind */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) NULL, /* Mikasa -- see below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) NULL, /* EB64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) NULL, /* EB66 -- see variation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) NULL, /* EB64+ -- see variation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) &alphabook1_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) &rawhide_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) NULL, /* K2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) &lynx_mv, /* Lynx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) &xl_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) NULL, /* EB164 -- see variation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) NULL, /* Noritake -- see below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) NULL, /* Cortex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) NULL, /* 29 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) &miata_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) NULL, /* XXM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) &takara_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) NULL, /* Yukon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) NULL, /* Tsunami -- see variation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) &wildfire_mv, /* Wildfire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) NULL, /* CUSCO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) &eiger_mv, /* Eiger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) NULL, /* Titan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) NULL, /* Marvel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static struct alpha_machine_vector *unofficial_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) NULL, /* 100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) &ruffian_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static struct alpha_machine_vector *api_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) NULL, /* 200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) &nautilus_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static struct alpha_machine_vector *alcor_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) &alcor_mv, &xlt_mv, &xlt_mv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static struct alpha_machine_vector *eb164_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) &eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv, &rx164_mv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static struct alpha_machine_vector *eb64p_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) &eb64p_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) &cabriolet_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) &cabriolet_mv /* AlphaPCI64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static struct alpha_machine_vector *eb66_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) &eb66_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) &eb66p_mv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static struct alpha_machine_vector *marvel_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) &marvel_ev7_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static struct alpha_machine_vector *titan_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) &titan_mv, /* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) &privateer_mv, /* privateer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) &titan_mv, /* falcon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) &privateer_mv, /* granite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static struct alpha_machine_vector *tsunami_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) &dp264_mv, /* dp264 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) &dp264_mv, /* warhol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) &dp264_mv, /* windjammer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) &monet_mv, /* monet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) &clipper_mv, /* clipper */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) &dp264_mv, /* goldrush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) &webbrick_mv, /* webbrick */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) &dp264_mv, /* catamaran */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) NULL, /* brisbane? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) NULL, /* melbourne? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) NULL, /* flying clipper? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) &shark_mv, /* shark */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* ??? Do we need to distinguish between Rawhides? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct alpha_machine_vector *vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* Search the system tables first... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) vec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (type < ARRAY_SIZE(systype_vecs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) vec = systype_vecs[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) } else if ((type > ST_API_BIAS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) (type - ST_API_BIAS) < ARRAY_SIZE(api_vecs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) vec = api_vecs[type - ST_API_BIAS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) } else if ((type > ST_UNOFFICIAL_BIAS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) (type - ST_UNOFFICIAL_BIAS) < ARRAY_SIZE(unofficial_vecs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) vec = unofficial_vecs[type - ST_UNOFFICIAL_BIAS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* If we've not found one, try for a variation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!vec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* Member ID is a bit-field. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned long member = (variation >> 10) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) cpu &= 0xffffffff; /* make it usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) case ST_DEC_ALCOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (member < ARRAY_SIZE(alcor_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) vec = alcor_vecs[alcor_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case ST_DEC_EB164:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (member < ARRAY_SIZE(eb164_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) vec = eb164_vecs[eb164_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* PC164 may show as EB164 variation with EV56 CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) but, since no true EB164 had anything but EV5... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (vec == &eb164_mv && cpu == EV56_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) vec = &pc164_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) case ST_DEC_EB64P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (member < ARRAY_SIZE(eb64p_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) vec = eb64p_vecs[eb64p_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case ST_DEC_EB66:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (member < ARRAY_SIZE(eb66_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) vec = eb66_vecs[eb66_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case ST_DEC_MARVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (member < ARRAY_SIZE(marvel_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) vec = marvel_vecs[marvel_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case ST_DEC_TITAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) vec = titan_vecs[0]; /* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (member < ARRAY_SIZE(titan_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) vec = titan_vecs[titan_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) case ST_DEC_TSUNAMI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (member < ARRAY_SIZE(tsunami_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) vec = tsunami_vecs[tsunami_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) case ST_DEC_1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (cpu == EV5_CPU || cpu == EV56_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) vec = &mikasa_primo_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) vec = &mikasa_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) case ST_DEC_NORITAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (cpu == EV5_CPU || cpu == EV56_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) vec = &noritake_primo_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) vec = &noritake_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) case ST_DEC_2100_A500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (cpu == EV5_CPU || cpu == EV56_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) vec = &sable_gamma_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) vec = &sable_mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static struct alpha_machine_vector * __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) get_sysvec_byname(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static struct alpha_machine_vector *all_vecs[] __initdata =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) &alcor_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) &alphabook1_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) &avanti_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) &cabriolet_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) &clipper_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) &dp264_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) &eb164_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) &eb64p_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) &eb66_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) &eb66p_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) &eiger_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) &jensen_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) &lx164_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) &lynx_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) &miata_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) &mikasa_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) &mikasa_primo_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) &monet_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) &nautilus_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) &noname_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) &noritake_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) &noritake_primo_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) &p2k_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) &pc164_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) &privateer_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) &rawhide_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) &ruffian_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) &rx164_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) &sable_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) &sable_gamma_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) &shark_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) &sx164_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) &takara_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) &webbrick_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) &wildfire_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) &xl_mv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) &xlt_mv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) for (i = 0; i < ARRAY_SIZE(all_vecs); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct alpha_machine_vector *mv = all_vecs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (strcasecmp(mv->vector_name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return mv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) get_sysnames(unsigned long type, unsigned long variation, unsigned long cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) char **type_name, char **variation_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) unsigned long member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* If not in the tables, make it UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) else set type name to family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (type < ARRAY_SIZE(systype_names)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) *type_name = systype_names[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) } else if ((type > ST_API_BIAS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) (type - ST_API_BIAS) < ARRAY_SIZE(api_names)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) *type_name = api_names[type - ST_API_BIAS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) } else if ((type > ST_UNOFFICIAL_BIAS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) (type - ST_UNOFFICIAL_BIAS) < ARRAY_SIZE(unofficial_names)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) *type_name = unofficial_names[type - ST_UNOFFICIAL_BIAS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) *type_name = sys_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) *variation_name = sys_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /* Set variation to "0"; if variation is zero, done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) *variation_name = systype_names[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (variation == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) member = (variation >> 10) & 0x3f; /* member ID is a bit-field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) cpu &= 0xffffffff; /* make it usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) switch (type) { /* select by family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) default: /* default to variation "0" for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) case ST_DEC_EB164:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (member >= ARRAY_SIZE(eb164_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) *variation_name = eb164_names[eb164_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* PC164 may show as EB164 variation, but with EV56 CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) so, since no true EB164 had anything but EV5... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (eb164_indices[member] == 0 && cpu == EV56_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) *variation_name = eb164_names[1]; /* make it PC164 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) case ST_DEC_ALCOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (member < ARRAY_SIZE(alcor_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) *variation_name = alcor_names[alcor_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) case ST_DEC_EB64P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (member < ARRAY_SIZE(eb64p_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) *variation_name = eb64p_names[eb64p_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) case ST_DEC_EB66:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (member < ARRAY_SIZE(eb66_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) *variation_name = eb66_names[eb66_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) case ST_DEC_MARVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (member < ARRAY_SIZE(marvel_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) *variation_name = marvel_names[marvel_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) case ST_DEC_RAWHIDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (member < ARRAY_SIZE(rawhide_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) *variation_name = rawhide_names[rawhide_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) case ST_DEC_TITAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) *variation_name = titan_names[0]; /* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (member < ARRAY_SIZE(titan_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) *variation_name = titan_names[titan_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) case ST_DEC_TSUNAMI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (member < ARRAY_SIZE(tsunami_indices))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) *variation_name = tsunami_names[tsunami_indices[member]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * A change was made to the HWRPB via an ECO and the following code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * tracks a part of the ECO. In HWRPB versions less than 5, the ECO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * was not implemented in the console firmware. If it's revision 5 or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * greater we can get the name of the platform as an ASCII string from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * the HWRPB. That's what this function does. It checks the revision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * level and if the string is in the HWRPB it returns the address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) * the string--a pointer to the name of the platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * - Pointer to a ASCII string if it's in the HWRPB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * - Pointer to a blank string if the data is not in the HWRPB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) platform_string(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct dsr_struct *dsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static char unk_system_string[] = "N/A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /* Go to the console for the string pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * If the rpb_vers is not 5 or greater the rpb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * is old and does not have this data in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (hwrpb->revision < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return (unk_system_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /* The Dynamic System Recognition struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * has the system platform name starting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * after the character count of the string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dsr = ((struct dsr_struct *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) ((char *)hwrpb + hwrpb->dsr_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return ((char *)dsr + (dsr->sysname_off +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) sizeof(long)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) get_nr_processors(struct percpu_struct *cpubase, unsigned long num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) struct percpu_struct *cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) cpu = (struct percpu_struct *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ((char *)cpubase + i*hwrpb->processor_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if ((cpu->flags & 0x1cc) == 0x1cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) show_cache_size (struct seq_file *f, const char *which, int shape)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (shape == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) seq_printf (f, "%s\t\t: n/a\n", which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) else if (shape == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) seq_printf (f, "%s\t\t: unknown\n", which);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) seq_printf (f, "%s\t\t: %dK, %d-way, %db line\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) which, shape >> 10, shape & 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 1 << ((shape >> 4) & 15));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) show_cpuinfo(struct seq_file *f, void *slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) extern struct unaligned_stat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) unsigned long count, va, pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) } unaligned[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static char cpu_names[][8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) "EV3", "EV4", "Simulate", "LCA4", "EV5", "EV45", "EV56",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) "EV6", "PCA56", "PCA57", "EV67", "EV68CB", "EV68AL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) "EV68CX", "EV7", "EV79", "EV69"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct percpu_struct *cpu = slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) unsigned int cpu_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) char *cpu_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) char *systype_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) char *sysvariation_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) int nr_processors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) unsigned long timer_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) cpu_index = (unsigned) (cpu->type - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) cpu_name = "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (cpu_index < ARRAY_SIZE(cpu_names))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) cpu_name = cpu_names[cpu_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) cpu->type, &systype_name, &sysvariation_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) nr_processors = get_nr_processors(cpu, hwrpb->nr_processors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) #if CONFIG_HZ == 1024 || CONFIG_HZ == 1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) timer_freq = (100UL * hwrpb->intr_freq) / 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) timer_freq = 100UL * CONFIG_HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) seq_printf(f, "cpu\t\t\t: Alpha\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) "cpu model\t\t: %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) "cpu variation\t\t: %ld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) "cpu revision\t\t: %ld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) "cpu serial number\t: %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) "system type\t\t: %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) "system variation\t: %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) "system revision\t\t: %ld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) "system serial number\t: %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) "cycle frequency [Hz]\t: %lu %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) "timer frequency [Hz]\t: %lu.%02lu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) "page size [bytes]\t: %ld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) "phys. address bits\t: %ld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) "max. addr. space #\t: %ld\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) "BogoMIPS\t\t: %lu.%02lu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) "kernel unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) "user unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) "platform string\t\t: %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) "cpus detected\t\t: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) cpu_name, cpu->variation, cpu->revision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) (char*)cpu->serial_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) systype_name, sysvariation_name, hwrpb->sys_revision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) (char*)hwrpb->ssn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) est_cycle_freq ? : hwrpb->cycle_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) est_cycle_freq ? "est." : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) timer_freq / 100, timer_freq % 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) hwrpb->pagesize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) hwrpb->pa_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) hwrpb->max_asn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) loops_per_jiffy / (500000/HZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) (loops_per_jiffy / (5000/HZ)) % 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) unaligned[0].count, unaligned[0].pc, unaligned[0].va,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) unaligned[1].count, unaligned[1].pc, unaligned[1].va,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) platform_string(), nr_processors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) seq_printf(f, "cpus active\t\t: %u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) "cpu active mask\t\t: %016lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) num_online_cpus(), cpumask_bits(cpu_possible_mask)[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) show_cache_size (f, "L1 Icache", alpha_l1i_cacheshape);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) show_cache_size (f, "L1 Dcache", alpha_l1d_cacheshape);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) show_cache_size (f, "L2 cache", alpha_l2_cacheshape);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) show_cache_size (f, "L3 cache", alpha_l3_cacheshape);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) read_mem_block(int *addr, int stride, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) long nloads = size / stride, cnt, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) __asm__ __volatile__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) " rpcc %0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) "1: ldl %3,0(%2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) " subq %1,1,%1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /* Next two XORs introduce an explicit data dependency between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) consecutive loads in the loop, which will give us true load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) latency. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) " xor %3,%2,%2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) " xor %3,%2,%2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) " addq %2,%4,%2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) " bne %1,1b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) " rpcc %3\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) " subl %3,%0,%0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) : "=&r" (cnt), "=&r" (nloads), "=&r" (addr), "=&r" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) : "r" (stride), "1" (nloads), "2" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return cnt / (size / stride);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) #define CSHAPE(totalsize, linesize, assoc) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ((totalsize & ~0xff) | (linesize << 4) | assoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* ??? EV5 supports up to 64M, but did the systems with more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 16M of BCACHE ever exist? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) #define MAX_BCACHE_SIZE 16*1024*1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* Note that the offchip caches are direct mapped on all Alphas. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) external_cache_probe(int minsize, int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) int cycles, prev_cycles = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) int stride = 1 << width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) long size = minsize, maxsize = MAX_BCACHE_SIZE * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (maxsize > (max_low_pfn + 1) << PAGE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) maxsize = 1 << (ilog2(max_low_pfn + 1) + PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) /* Get the first block cached. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) read_mem_block(__va(0), stride, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) while (size < maxsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) /* Get an average load latency in cycles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) cycles = read_mem_block(__va(0), stride, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (cycles > prev_cycles * 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) /* Fine, we exceed the cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) printk("%ldK Bcache detected; load hit latency %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) "cycles, load miss latency %d cycles\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) size >> 11, prev_cycles, cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return CSHAPE(size >> 1, width, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) /* Try to get the next block cached. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) read_mem_block(__va(size), stride, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) prev_cycles = cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) size <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return -1; /* No BCACHE found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static void __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) determine_cpu_caches (unsigned int cpu_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) int L1I, L1D, L2, L3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) switch (cpu_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) case EV4_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) case EV45_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (cpu_type == EV4_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) L1I = CSHAPE(8*1024, 5, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) L1I = CSHAPE(16*1024, 5, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) L1D = L1I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) L3 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /* BIU_CTL is a write-only Abox register. PALcode has a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) shadow copy, and may be available from some versions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) of the CSERVE PALcall. If we can get it, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) unsigned long biu_ctl, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) size = 128*1024 * (1 << ((biu_ctl >> 28) & 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) L2 = CSHAPE (size, 5, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) Unfortunately, we can't rely on that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) L2 = external_cache_probe(128*1024, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) case LCA4_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) unsigned long car, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) L1I = L1D = CSHAPE(8*1024, 5, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) L3 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) car = *(vuip) phys_to_virt (0x120000078UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) size = 64*1024 * (1 << ((car >> 5) & 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* No typo -- 8 byte cacheline size. Whodathunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) L2 = (car & 1 ? CSHAPE (size, 3, 1) : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) case EV5_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) case EV56_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) unsigned long sc_ctl, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) L1I = L1D = CSHAPE(8*1024, 5, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) /* Check the line size of the Scache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) sc_ctl = *(vulp) phys_to_virt (0xfffff000a8UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) width = sc_ctl & 0x1000 ? 6 : 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) L2 = CSHAPE (96*1024, width, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) /* BC_CONTROL and BC_CONFIG are write-only IPRs. PALcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) has a shadow copy, and may be available from some versions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) of the CSERVE PALcall. If we can get it, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) unsigned long bc_control, bc_config, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) size = 1024*1024 * (1 << ((bc_config & 7) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) L3 = (bc_control & 1 ? CSHAPE (size, width, 1) : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) Unfortunately, we can't rely on that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) L3 = external_cache_probe(1024*1024, width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) case PCA56_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) case PCA57_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (cpu_type == PCA56_CPU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) L1I = CSHAPE(16*1024, 6, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) L1D = CSHAPE(8*1024, 5, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) L1I = CSHAPE(32*1024, 6, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) L1D = CSHAPE(16*1024, 5, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) L3 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) unsigned long cbox_config, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) cbox_config = *(vulp) phys_to_virt (0xfffff00008UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) size = 512*1024 * (1 << ((cbox_config >> 12) & 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) L2 = ((cbox_config >> 31) & 1 ? CSHAPE (size, 6, 1) : -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) L2 = external_cache_probe(512*1024, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) case EV6_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) case EV67_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) case EV68CB_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) case EV68AL_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) case EV68CX_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case EV69_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) L1I = L1D = CSHAPE(64*1024, 6, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) L2 = external_cache_probe(1024*1024, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) L3 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) case EV7_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) case EV79_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) L1I = L1D = CSHAPE(64*1024, 6, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) L2 = CSHAPE(7*1024*1024/4, 6, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) L3 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* Nothing known about this cpu type. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) L1I = L1D = L2 = L3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) alpha_l1i_cacheshape = L1I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) alpha_l1d_cacheshape = L1D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) alpha_l2_cacheshape = L2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) alpha_l3_cacheshape = L3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * We show only CPU #0 info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) c_start(struct seq_file *f, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) return *pos ? NULL : (char *)hwrpb + hwrpb->processor_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) c_next(struct seq_file *f, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) (*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) c_stop(struct seq_file *f, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) const struct seq_operations cpuinfo_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) .start = c_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) .next = c_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .stop = c_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .show = show_cpuinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) alpha_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /* FIXME FIXME FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* If we are using SRM and serial console, just hard halt here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (alpha_using_srm && srmcons_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) __halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) static __init int add_pcspkr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct platform_device *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) pd = platform_device_alloc("pcspkr", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (!pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) ret = platform_device_add(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) platform_device_put(pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) device_initcall(add_pcspkr);