diff options
Diffstat (limited to 'arch/ia64/sn/kernel/setup.c')
-rw-r--r-- | arch/ia64/sn/kernel/setup.c | 786 |
1 files changed, 0 insertions, 786 deletions
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c deleted file mode 100644 index e6a5049ef503..000000000000 --- a/arch/ia64/sn/kernel/setup.c +++ /dev/null @@ -1,786 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All rights reserved. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/kernel.h> -#include <linux/kdev_t.h> -#include <linux/string.h> -#include <linux/screen_info.h> -#include <linux/console.h> -#include <linux/timex.h> -#include <linux/sched.h> -#include <linux/ioport.h> -#include <linux/mm.h> -#include <linux/serial.h> -#include <linux/irq.h> -#include <linux/memblock.h> -#include <linux/mmzone.h> -#include <linux/interrupt.h> -#include <linux/acpi.h> -#include <linux/compiler.h> -#include <linux/root_dev.h> -#include <linux/nodemask.h> -#include <linux/pm.h> -#include <linux/efi.h> - -#include <asm/io.h> -#include <asm/sal.h> -#include <asm/machvec.h> -#include <asm/processor.h> -#include <asm/vga.h> -#include <asm/setup.h> -#include <asm/sn/arch.h> -#include <asm/sn/addrs.h> -#include <asm/sn/pda.h> -#include <asm/sn/nodepda.h> -#include <asm/sn/sn_cpuid.h> -#include <asm/sn/simulator.h> -#include <asm/sn/leds.h> -#include <asm/sn/bte.h> -#include <asm/sn/shub_mmr.h> -#include <asm/sn/clksupport.h> -#include <asm/sn/sn_sal.h> -#include <asm/sn/geo.h> -#include <asm/sn/sn_feature_sets.h> -#include "xtalk/xwidgetdev.h" -#include "xtalk/hubdev.h" -#include <asm/sn/klconfig.h> - - -DEFINE_PER_CPU(struct pda_s, pda_percpu); - -#define MAX_PHYS_MEMORY (1UL << IA64_MAX_PHYS_BITS) /* Max physical address supported */ - -extern void bte_init_node(nodepda_t *, cnodeid_t); - -extern void sn_timer_init(void); -extern unsigned long last_time_offset; -extern void (*ia64_mark_idle) (int); -extern void snidle(int); - -unsigned long sn_rtc_cycles_per_second; -EXPORT_SYMBOL(sn_rtc_cycles_per_second); - -DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); -EXPORT_PER_CPU_SYMBOL(__sn_hub_info); - -DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); -EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); - -DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); -EXPORT_PER_CPU_SYMBOL(__sn_nodepda); - -char sn_system_serial_number_string[128]; -EXPORT_SYMBOL(sn_system_serial_number_string); -u64 sn_partition_serial_number; -EXPORT_SYMBOL(sn_partition_serial_number); -u8 sn_partition_id; -EXPORT_SYMBOL(sn_partition_id); -u8 sn_system_size; -EXPORT_SYMBOL(sn_system_size); -u8 sn_sharing_domain_size; -EXPORT_SYMBOL(sn_sharing_domain_size); -u8 sn_coherency_id; -EXPORT_SYMBOL(sn_coherency_id); -u8 sn_region_size; -EXPORT_SYMBOL(sn_region_size); -int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ - -short physical_node_map[MAX_NUMALINK_NODES]; -static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS]; - -EXPORT_SYMBOL(physical_node_map); - -int num_cnodes; - -static void sn_init_pdas(char **); -static void build_cnode_tables(void); - -static nodepda_t *nodepdaindr[MAX_COMPACT_NODES]; - -/* - * The format of "screen_info" is strange, and due to early i386-setup - * code. This is just enough to make the console code think we're on a - * VGA color display. - */ -struct screen_info sn_screen_info = { - .orig_x = 0, - .orig_y = 0, - .orig_video_mode = 3, - .orig_video_cols = 80, - .orig_video_ega_bx = 3, - .orig_video_lines = 25, - .orig_video_isVGA = 1, - .orig_video_points = 16 -}; - -/* - * This routine can only be used during init, since - * smp_boot_data is an init data structure. - * We have to use smp_boot_data.cpu_phys_id to find - * the physical id of the processor because the normal - * cpu_physical_id() relies on data structures that - * may not be initialized yet. - */ - -static int __init pxm_to_nasid(int pxm) -{ - int i; - int nid; - - nid = pxm_to_node(pxm); - for (i = 0; i < num_node_memblks; i++) { - if (node_memblk[i].nid == nid) { - return NASID_GET(node_memblk[i].start_paddr); - } - } - return -1; -} - -/** - * early_sn_setup - early setup routine for SN platforms - * - * Sets up an initial console to aid debugging. Intended primarily - * for bringup. See start_kernel() in init/main.c. - */ - -void __init early_sn_setup(void) -{ - efi_system_table_t *efi_systab; - efi_config_table_t *config_tables; - struct ia64_sal_systab *sal_systab; - struct ia64_sal_desc_entry_point *ep; - char *p; - int i, j; - - /* - * Parse enough of the SAL tables to locate the SAL entry point. Since, console - * IO on SN2 is done via SAL calls, early_printk won't work without this. - * - * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c. - * Any changes to those file may have to be made here as well. - */ - efi_systab = (efi_system_table_t *) __va(ia64_boot_param->efi_systab); - config_tables = __va(efi_systab->tables); - for (i = 0; i < efi_systab->nr_tables; i++) { - if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == - 0) { - sal_systab = __va(config_tables[i].table); - p = (char *)(sal_systab + 1); - for (j = 0; j < sal_systab->entry_count; j++) { - if (*p == SAL_DESC_ENTRY_POINT) { - ep = (struct ia64_sal_desc_entry_point - *)p; - ia64_sal_handler_init(__va - (ep->sal_proc), - __va(ep->gp)); - return; - } - p += SAL_DESC_SIZE(*p); - } - } - } - /* Uh-oh, SAL not available?? */ - printk(KERN_ERR "failed to find SAL entry point\n"); -} - -extern int platform_intr_list[]; -static int shub_1_1_found; - -/* - * sn_check_for_wars - * - * Set flag for enabling shub specific wars - */ - -static inline int is_shub_1_1(int nasid) -{ - unsigned long id; - int rev; - - if (is_shub2()) - return 0; - id = REMOTE_HUB_L(nasid, SH1_SHUB_ID); - rev = (id & SH1_SHUB_ID_REVISION_MASK) >> SH1_SHUB_ID_REVISION_SHFT; - return rev <= 2; -} - -static void sn_check_for_wars(void) -{ - int cnode; - - if (is_shub2()) { - /* none yet */ - } else { - for_each_online_node(cnode) { - if (is_shub_1_1(cnodeid_to_nasid(cnode))) - shub_1_1_found = 1; - } - } -} - -/* - * Scan the EFI PCDP table (if it exists) for an acceptable VGA console - * output device. If one exists, pick it and set sn_legacy_{io,mem} to - * reflect the bus offsets needed to address it. - * - * Since pcdp support in SN is not supported in the 2.4 kernel (or at least - * the one lbs is based on) just declare the needed structs here. - * - * Reference spec http://www.dig64.org/specifications/DIG64_PCDPv20.pdf - * - * Returns 0 if no acceptable vga is found, !0 otherwise. - * - * Note: This stuff is duped here because Altix requires the PCDP to - * locate a usable VGA device due to lack of proper ACPI support. Structures - * could be used from drivers/firmware/pcdp.h, but it was decided that moving - * this file to a more public location just for Altix use was undesirable. - */ - -struct hcdp_uart_desc { - u8 pad[45]; -}; - -struct pcdp { - u8 signature[4]; /* should be 'HCDP' */ - u32 length; - u8 rev; /* should be >=3 for pcdp, <3 for hcdp */ - u8 sum; - u8 oem_id[6]; - u64 oem_tableid; - u32 oem_rev; - u32 creator_id; - u32 creator_rev; - u32 num_type0; - struct hcdp_uart_desc uart[0]; /* num_type0 of these */ - /* pcdp descriptors follow */ -} __attribute__((packed)); - -struct pcdp_device_desc { - u8 type; - u8 primary; - u16 length; - u16 index; - /* interconnect specific structure follows */ - /* device specific structure follows that */ -} __attribute__((packed)); - -struct pcdp_interface_pci { - u8 type; /* 1 == pci */ - u8 reserved; - u16 length; - u8 segment; - u8 bus; - u8 dev; - u8 fun; - u16 devid; - u16 vendid; - u32 acpi_interrupt; - u64 mmio_tra; - u64 ioport_tra; - u8 flags; - u8 translation; -} __attribute__((packed)); - -struct pcdp_vga_device { - u8 num_eas_desc; - /* ACPI Extended Address Space Desc follows */ -} __attribute__((packed)); - -/* from pcdp_device_desc.primary */ -#define PCDP_PRIMARY_CONSOLE 0x01 - -/* from pcdp_device_desc.type */ -#define PCDP_CONSOLE_INOUT 0x0 -#define PCDP_CONSOLE_DEBUG 0x1 -#define PCDP_CONSOLE_OUT 0x2 -#define PCDP_CONSOLE_IN 0x3 -#define PCDP_CONSOLE_TYPE_VGA 0x8 - -#define PCDP_CONSOLE_VGA (PCDP_CONSOLE_TYPE_VGA | PCDP_CONSOLE_OUT) - -/* from pcdp_interface_pci.type */ -#define PCDP_IF_PCI 1 - -/* from pcdp_interface_pci.translation */ -#define PCDP_PCI_TRANS_IOPORT 0x02 -#define PCDP_PCI_TRANS_MMIO 0x01 - -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) -static void -sn_scan_pcdp(void) -{ - u8 *bp; - struct pcdp *pcdp; - struct pcdp_device_desc device; - struct pcdp_interface_pci if_pci; - extern struct efi efi; - - if (efi.hcdp == EFI_INVALID_TABLE_ADDR) - return; /* no hcdp/pcdp table */ - - pcdp = __va(efi.hcdp); - - if (pcdp->rev < 3) - return; /* only support PCDP (rev >= 3) */ - - for (bp = (u8 *)&pcdp->uart[pcdp->num_type0]; - bp < (u8 *)pcdp + pcdp->length; - bp += device.length) { - memcpy(&device, bp, sizeof(device)); - if (! (device.primary & PCDP_PRIMARY_CONSOLE)) - continue; /* not primary console */ - - if (device.type != PCDP_CONSOLE_VGA) - continue; /* not VGA descriptor */ - - memcpy(&if_pci, bp+sizeof(device), sizeof(if_pci)); - if (if_pci.type != PCDP_IF_PCI) - continue; /* not PCI interconnect */ - - if (if_pci.translation & PCDP_PCI_TRANS_IOPORT) - vga_console_iobase = if_pci.ioport_tra; - - if (if_pci.translation & PCDP_PCI_TRANS_MMIO) - vga_console_membase = - if_pci.mmio_tra | __IA64_UNCACHED_OFFSET; - - break; /* once we find the primary, we're done */ - } -} -#endif - -static unsigned long sn2_rtc_initial; - -/** - * sn_setup - SN platform setup routine - * @cmdline_p: kernel command line - * - * Handles platform setup for SN machines. This includes determining - * the RTC frequency (via a SAL call), initializing secondary CPUs, and - * setting up per-node data areas. The console is also initialized here. - */ -void __init sn_setup(char **cmdline_p) -{ - long status, ticks_per_sec, drift; - u32 version = sn_sal_rev(); - extern void sn_cpu_init(void); - - sn2_rtc_initial = rtc_time(); - ia64_sn_plat_set_error_handling_features(); // obsolete - ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); - ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); - /* - * Note: The calls to notify the PROM of ACPI and PCI Segment - * support must be done prior to acpi_load_tables(), as - * an ACPI capable PROM will rebuild the DSDT as result - * of the call. - */ - ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE); - ia64_sn_set_os_feature(OSF_ACPI_ENABLE); - - /* Load the new DSDT and SSDT tables into the global table list. */ - acpi_table_init(); - -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - /* - * Handle SN vga console. - * - * SN systems do not have enough ACPI table information - * being passed from prom to identify VGA adapters and the legacy - * addresses to access them. Until that is done, SN systems rely - * on the PCDP table to identify the primary VGA console if one - * exists. - * - * However, kernel PCDP support is optional, and even if it is built - * into the kernel, it will not be used if the boot cmdline contains - * console= directives. - * - * So, to work around this mess, we duplicate some of the PCDP code - * here so that the primary VGA console (as defined by PCDP) will - * work on SN systems even if a different console (e.g. serial) is - * selected on the boot line (or CONFIG_EFI_PCDP is off). - */ - - if (! vga_console_membase) - sn_scan_pcdp(); - - /* - * Setup legacy IO space. - * vga_console_iobase maps to PCI IO Space address 0 on the - * bus containing the VGA console. - */ - if (vga_console_iobase) { - io_space[0].mmio_base = - (unsigned long) ioremap(vga_console_iobase, 0); - io_space[0].sparse = 0; - } - - if (vga_console_membase) { - /* usable vga ... make tty0 the preferred default console */ - if (!strstr(*cmdline_p, "console=")) - add_preferred_console("tty", 0, NULL); - } else { - printk(KERN_DEBUG "SGI: Disabling VGA console\n"); - if (!strstr(*cmdline_p, "console=")) - add_preferred_console("ttySG", 0, NULL); -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#else - conswitchp = NULL; -#endif /* CONFIG_DUMMY_CONSOLE */ - } -#endif /* def(CONFIG_VT) && def(CONFIG_VGA_CONSOLE) */ - - MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY; - - /* - * Build the tables for managing cnodes. - */ - build_cnode_tables(); - - status = - ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, - &drift); - if (status != 0 || ticks_per_sec < 100000) { - printk(KERN_WARNING - "unable to determine platform RTC clock frequency, guessing.\n"); - /* PROM gives wrong value for clock freq. so guess */ - sn_rtc_cycles_per_second = 1000000000000UL / 30000UL; - } else - sn_rtc_cycles_per_second = ticks_per_sec; - - platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; - - printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); - - /* - * we set the default root device to /dev/hda - * to make simulation easy - */ - ROOT_DEV = Root_HDA1; - - /* - * Create the PDAs and NODEPDAs for all the cpus. - */ - sn_init_pdas(cmdline_p); - - ia64_mark_idle = &snidle; - - /* - * For the bootcpu, we do this here. All other cpus will make the - * call as part of cpu_init in slave cpu initialization. - */ - sn_cpu_init(); - -#ifdef CONFIG_SMP - init_smp_config(); -#endif - screen_info = sn_screen_info; - - sn_timer_init(); - - /* - * set pm_power_off to a SAL call to allow - * sn machines to power off. The SAL call can be replaced - * by an ACPI interface call when ACPI is fully implemented - * for sn. - */ - pm_power_off = ia64_sn_power_down; - current->thread.flags |= IA64_THREAD_MIGRATION; -} - -/** - * sn_init_pdas - setup node data areas - * - * One time setup for Node Data Area. Called by sn_setup(). - */ -static void __init sn_init_pdas(char **cmdline_p) -{ - cnodeid_t cnode; - - /* - * Allocate & initialize the nodepda for each node. - */ - for_each_online_node(cnode) { - nodepdaindr[cnode] = - memblock_alloc_node(sizeof(nodepda_t), SMP_CACHE_BYTES, - cnode); - if (!nodepdaindr[cnode]) - panic("%s: Failed to allocate %lu bytes align=0x%x nid=%d\n", - __func__, sizeof(nodepda_t), SMP_CACHE_BYTES, - cnode); - memset(nodepdaindr[cnode]->phys_cpuid, -1, - sizeof(nodepdaindr[cnode]->phys_cpuid)); - spin_lock_init(&nodepdaindr[cnode]->ptc_lock); - } - - /* - * Allocate & initialize nodepda for TIOs. For now, put them on node 0. - */ - for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++) { - nodepdaindr[cnode] = - memblock_alloc_node(sizeof(nodepda_t), SMP_CACHE_BYTES, 0); - if (!nodepdaindr[cnode]) - panic("%s: Failed to allocate %lu bytes align=0x%x nid=%d\n", - __func__, sizeof(nodepda_t), SMP_CACHE_BYTES, - cnode); - } - - - /* - * Now copy the array of nodepda pointers to each nodepda. - */ - for (cnode = 0; cnode < num_cnodes; cnode++) - memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, - sizeof(nodepdaindr)); - - /* - * Set up IO related platform-dependent nodepda fields. - * The following routine actually sets up the hubinfo struct - * in nodepda. - */ - for_each_online_node(cnode) { - bte_init_node(nodepdaindr[cnode], cnode); - } - - /* - * Initialize the per node hubdev. This includes IO Nodes and - * headless/memless nodes. - */ - for (cnode = 0; cnode < num_cnodes; cnode++) { - hubdev_init_node(nodepdaindr[cnode], cnode); - } -} - -/** - * sn_cpu_init - initialize per-cpu data areas - * @cpuid: cpuid of the caller - * - * Called during cpu initialization on each cpu as it starts. - * Currently, initializes the per-cpu data area for SNIA. - * Also sets up a few fields in the nodepda. Also known as - * platform_cpu_init() by the ia64 machvec code. - */ -void sn_cpu_init(void) -{ - int cpuid; - int cpuphyid; - int nasid; - int subnode; - int slice; - int cnode; - int i; - static int wars_have_been_checked, set_cpu0_number; - - cpuid = smp_processor_id(); - if (cpuid == 0 && IS_MEDUSA()) { - if (ia64_sn_is_fake_prom()) - sn_prom_type = 2; - else - sn_prom_type = 1; - printk(KERN_INFO "Running on medusa with %s PROM\n", - (sn_prom_type == 1) ? "real" : "fake"); - } - - memset(pda, 0, sizeof(*pda)); - if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, - &sn_hub_info->nasid_bitmask, - &sn_hub_info->nasid_shift, - &sn_system_size, &sn_sharing_domain_size, - &sn_partition_id, &sn_coherency_id, - &sn_region_size)) - BUG(); - sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; - - /* - * Don't check status. The SAL call is not supported on all PROMs - * but a failure is harmless. - * Architecturally, cpu_init is always called twice on cpu 0. We - * should set cpu_number on cpu 0 once. - */ - if (cpuid == 0) { - if (!set_cpu0_number) { - (void) ia64_sn_set_cpu_number(cpuid); - set_cpu0_number = 1; - } - } else - (void) ia64_sn_set_cpu_number(cpuid); - - /* - * The boot cpu makes this call again after platform initialization is - * complete. - */ - if (nodepdaindr[0] == NULL) - return; - - for (i = 0; i < MAX_PROM_FEATURE_SETS; i++) - if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0) - break; - - cpuphyid = get_sapicid(); - - if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice)) - BUG(); - - for (i=0; i < MAX_NUMNODES; i++) { - if (nodepdaindr[i]) { - nodepdaindr[i]->phys_cpuid[cpuid].nasid = nasid; - nodepdaindr[i]->phys_cpuid[cpuid].slice = slice; - nodepdaindr[i]->phys_cpuid[cpuid].subnode = subnode; - } - } - - cnode = nasid_to_cnodeid(nasid); - - __this_cpu_write(__sn_nodepda, nodepdaindr[cnode]); - - pda->led_address = - (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT)); - pda->led_state = LED_ALWAYS_SET; - pda->hb_count = HZ / 2; - pda->hb_state = 0; - pda->idle_flag = 0; - - if (cpuid != 0) { - /* copy cpu 0's sn_cnodeid_to_nasid table to this cpu's */ - memcpy(sn_cnodeid_to_nasid, - (&per_cpu(__sn_cnodeid_to_nasid, 0)), - sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); - } - - /* - * Check for WARs. - * Only needs to be done once, on BSP. - * Has to be done after loop above, because it uses this cpu's - * sn_cnodeid_to_nasid table which was just initialized if this - * isn't cpu 0. - * Has to be done before assignment below. - */ - if (!wars_have_been_checked) { - sn_check_for_wars(); - wars_have_been_checked = 1; - } - sn_hub_info->shub_1_1_found = shub_1_1_found; - - /* - * Set up addresses of PIO/MEM write status registers. - */ - { - u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0}; - u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_2, - SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3}; - u64 *pio; - pio = is_shub1() ? pio1 : pio2; - pda->pio_write_status_addr = - (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, pio[slice]); - pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0; - } - - /* - * WAR addresses for SHUB 1.x. - */ - if (local_node_data->active_cpu_count++ == 0 && is_shub1()) { - int buddy_nasid; - buddy_nasid = - cnodeid_to_nasid(numa_node_id() == - num_online_nodes() - 1 ? 0 : numa_node_id() + 1); - pda->pio_shub_war_cam_addr = - (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, - SH1_PI_CAM_CONTROL); - } -} - -/* - * Build tables for converting between NASIDs and cnodes. - */ -static inline int __init board_needs_cnode(int type) -{ - return (type == KLTYPE_SNIA || type == KLTYPE_TIO); -} - -void __init build_cnode_tables(void) -{ - int nasid; - int node; - lboard_t *brd; - - memset(physical_node_map, -1, sizeof(physical_node_map)); - memset(sn_cnodeid_to_nasid, -1, - sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); - - /* - * First populate the tables with C/M bricks. This ensures that - * cnode == node for all C & M bricks. - */ - for_each_online_node(node) { - nasid = pxm_to_nasid(node_to_pxm(node)); - sn_cnodeid_to_nasid[node] = nasid; - physical_node_map[nasid] = node; - } - - /* - * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node - * limit on the number of nodes, we can't use the generic node numbers - * for this. Note that num_cnodes is incremented below as TIOs or - * headless/memoryless nodes are discovered. - */ - num_cnodes = num_online_nodes(); - - /* fakeprom does not support klgraph */ - if (IS_RUNNING_ON_FAKE_PROM()) - return; - - /* Find TIOs & headless/memoryless nodes and add them to the tables */ - for_each_online_node(node) { - kl_config_hdr_t *klgraph_header; - nasid = cnodeid_to_nasid(node); - klgraph_header = ia64_sn_get_klconfig_addr(nasid); - BUG_ON(klgraph_header == NULL); - brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); - while (brd) { - if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) { - sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid; - physical_node_map[brd->brd_nasid] = num_cnodes++; - } - brd = find_lboard_next(brd); - } - } -} - -int -nasid_slice_to_cpuid(int nasid, int slice) -{ - long cpu; - - for (cpu = 0; cpu < nr_cpu_ids; cpu++) - if (cpuid_to_nasid(cpu) == nasid && - cpuid_to_slice(cpu) == slice) - return cpu; - - return -1; -} - -int sn_prom_feature_available(int id) -{ - if (id >= BITS_PER_LONG * MAX_PROM_FEATURE_SETS) - return 0; - return test_bit(id, sn_prom_features); -} - -void -sn_kernel_launch_event(void) -{ - /* ignore status until we understand possible failure, if any*/ - if (ia64_sn_kernel_launch_event()) - printk(KERN_ERR "KEXEC is not supported in this PROM, Please update the PROM.\n"); -} -EXPORT_SYMBOL(sn_prom_feature_available); - |