提交 7d14f145 编写于 作者: L Linus Torvalds

Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] New IA64 core/thread detection patch
  [IA64] Increase max node count on SN platforms
  [IA64] Increase max node count on SN platforms
  [IA64] Increase max node count on SN platforms
  [IA64] Increase max node count on SN platforms
  [IA64] Tollhouse HP: IA64 arch changes
  [IA64] cleanup dig_irq_init
  [IA64] MCA recovery: kernel context recovery table
  IA64: Use early_parm to handle mvec_name and nomca
  [IA64] move patchlist and machvec into init section
  [IA64] add init declaration - nolwsys
  [IA64] add init declaration - gate page functions
  [IA64] add init declaration to memory initialization functions
  [IA64] add init declaration to cpu initialization functions
  [IA64] add __init declaration to mca functions
  [IA64] Ignore disabled Local SAPIC Affinity Structure in SRAT
  [IA64] sn_check_intr: use ia64_get_irr()
  [IA64] fix ia64 is_hugepage_only_range
......@@ -252,6 +252,15 @@ config NR_CPUS
than 64 will cause the use of a CPU mask array, causing a small
performance hit.
config IA64_NR_NODES
int "Maximum number of NODEs (256-1024)" if (IA64_SGI_SN2 || IA64_GENERIC)
range 256 1024
depends on IA64_SGI_SN2 || IA64_GENERIC
default "256"
help
This option specifies the maximum number of nodes in your SSI system.
If in doubt, use the default.
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
depends on SMP && EXPERIMENTAL
......
......@@ -116,6 +116,7 @@ CONFIG_IOSAPIC=y
CONFIG_FORCE_MAX_ZONEORDER=17
CONFIG_SMP=y
CONFIG_NR_CPUS=512
CONFIG_IA64_NR_NODES=256
CONFIG_HOTPLUG_CPU=y
# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
......
......@@ -116,6 +116,7 @@ CONFIG_IA64_SGI_SN_XP=m
CONFIG_FORCE_MAX_ZONEORDER=17
CONFIG_SMP=y
CONFIG_NR_CPUS=1024
CONFIG_IA64_NR_NODES=256
# CONFIG_HOTPLUG_CPU is not set
CONFIG_SCHED_SMT=y
CONFIG_PREEMPT=y
......
......@@ -116,6 +116,7 @@ CONFIG_IOSAPIC=y
CONFIG_FORCE_MAX_ZONEORDER=17
CONFIG_SMP=y
CONFIG_NR_CPUS=512
CONFIG_IA64_NR_NODES=256
CONFIG_HOTPLUG_CPU=y
# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
......
......@@ -69,8 +69,3 @@ dig_setup (char **cmdline_p)
screen_info.orig_video_isVGA = 1; /* XXX fake */
screen_info.orig_video_ega_bx = 3; /* XXX fake */
}
void __init
dig_irq_init (void)
{
}
......@@ -420,6 +420,26 @@ int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS];
int __initdata nid_to_pxm_map[MAX_NUMNODES];
static struct acpi_table_slit __initdata *slit_table;
static int get_processor_proximity_domain(struct acpi_table_processor_affinity *pa)
{
int pxm;
pxm = pa->proximity_domain;
if (ia64_platform_is("sn2"))
pxm += pa->reserved[0] << 8;
return pxm;
}
static int get_memory_proximity_domain(struct acpi_table_memory_affinity *ma)
{
int pxm;
pxm = ma->proximity_domain;
if (ia64_platform_is("sn2"))
pxm += ma->reserved1[0] << 8;
return pxm;
}
/*
* ACPI 2.0 SLIT (System Locality Information Table)
* http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
......@@ -443,13 +463,20 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
void __init
acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
{
int pxm;
if (!pa->flags.enabled)
return;
pxm = get_processor_proximity_domain(pa);
/* record this node in proximity bitmap */
pxm_bit_set(pa->proximity_domain);
pxm_bit_set(pxm);
node_cpuid[srat_num_cpus].phys_id =
(pa->apic_id << 8) | (pa->lsapic_eid);
/* nid should be overridden as logical node id later */
node_cpuid[srat_num_cpus].nid = pa->proximity_domain;
node_cpuid[srat_num_cpus].nid = pxm;
srat_num_cpus++;
}
......@@ -457,10 +484,10 @@ void __init
acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
{
unsigned long paddr, size;
u8 pxm;
int pxm;
struct node_memblk_s *p, *q, *pend;
pxm = ma->proximity_domain;
pxm = get_memory_proximity_domain(ma);
/* fill node memory chunk structure */
paddr = ma->base_addr_hi;
......
......@@ -865,6 +865,7 @@ ENTRY(interrupt)
;;
SAVE_REST
;;
MCA_RECOVER_RANGE(interrupt)
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
mov out0=cr.ivr // pass cr.ivr as first arg
add out1=16,sp // pass pointer to pt_regs as second arg
......
......@@ -14,7 +14,15 @@
struct ia64_machine_vector ia64_mv;
EXPORT_SYMBOL(ia64_mv);
static struct ia64_machine_vector *
static __initdata const char *mvec_name;
static __init int setup_mvec(char *s)
{
mvec_name = s;
return 0;
}
early_param("machvec", setup_mvec);
static struct ia64_machine_vector * __init
lookup_machvec (const char *name)
{
extern struct ia64_machine_vector machvec_start[];
......@@ -33,10 +41,13 @@ machvec_init (const char *name)
{
struct ia64_machine_vector *mv;
if (!name)
name = mvec_name ? mvec_name : acpi_get_sysname();
mv = lookup_machvec(name);
if (!mv) {
panic("generic kernel failed to find machine vector for platform %s!", name);
}
if (!mv)
panic("generic kernel failed to find machine vector for"
" platform %s!", name);
ia64_mv = *mv;
printk(KERN_INFO "booting generic kernel on platform %s\n", name);
}
......
......@@ -83,6 +83,7 @@
#include <asm/irq.h>
#include <asm/hw_irq.h>
#include "mca_drv.h"
#include "entry.h"
#if defined(IA64_MCA_DEBUG_INFO)
......@@ -133,7 +134,7 @@ static int cpe_poll_enabled = 1;
extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
static int mca_init;
static int mca_init __initdata;
static void inline
......@@ -184,7 +185,7 @@ static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
* Inputs : info_type (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
* Outputs : None
*/
static void
static void __init
ia64_log_init(int sal_info_type)
{
u64 max_size = 0;
......@@ -281,6 +282,50 @@ ia64_mca_log_sal_error_record(int sal_info_type)
ia64_sal_clear_state_info(sal_info_type);
}
/*
* search_mca_table
* See if the MCA surfaced in an instruction range
* that has been tagged as recoverable.
*
* Inputs
* first First address range to check
* last Last address range to check
* ip Instruction pointer, address we are looking for
*
* Return value:
* 1 on Success (in the table)/ 0 on Failure (not in the table)
*/
int
search_mca_table (const struct mca_table_entry *first,
const struct mca_table_entry *last,
unsigned long ip)
{
const struct mca_table_entry *curr;
u64 curr_start, curr_end;
curr = first;
while (curr <= last) {
curr_start = (u64) &curr->start_addr + curr->start_addr;
curr_end = (u64) &curr->end_addr + curr->end_addr;
if ((ip >= curr_start) && (ip <= curr_end)) {
return 1;
}
curr++;
}
return 0;
}
/* Given an address, look for it in the mca tables. */
int mca_recover_range(unsigned long addr)
{
extern struct mca_table_entry __start___mca_table[];
extern struct mca_table_entry __stop___mca_table[];
return search_mca_table(__start___mca_table, __stop___mca_table-1, addr);
}
EXPORT_SYMBOL_GPL(mca_recover_range);
#ifdef CONFIG_ACPI
int cpe_vector = -1;
......@@ -355,7 +400,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
* Outputs
* None
*/
static void
static void __init
ia64_mca_register_cpev (int cpev)
{
/* Register the CPE interrupt vector with SAL */
......@@ -386,7 +431,7 @@ ia64_mca_register_cpev (int cpev)
* Outputs
* None
*/
void
void __cpuinit
ia64_mca_cmc_vector_setup (void)
{
cmcv_reg_t cmcv;
......@@ -747,31 +792,34 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
ia64_mca_modify_comm(previous_current);
goto no_mod;
}
if (r13 != sos->prev_IA64_KR_CURRENT) {
msg = "inconsistent previous current and r13";
goto no_mod;
}
if ((r12 - r13) >= KERNEL_STACK_SIZE) {
msg = "inconsistent r12 and r13";
goto no_mod;
}
if ((ar_bspstore - r13) >= KERNEL_STACK_SIZE) {
msg = "inconsistent ar.bspstore and r13";
goto no_mod;
}
va.p = old_bspstore;
if (va.f.reg < 5) {
msg = "old_bspstore is in the wrong region";
goto no_mod;
}
if ((ar_bsp - r13) >= KERNEL_STACK_SIZE) {
msg = "inconsistent ar.bsp and r13";
goto no_mod;
}
size += (ia64_rse_skip_regs(old_bspstore, slots) - old_bspstore) * 8;
if (ar_bspstore + size > r12) {
msg = "no room for blocked state";
goto no_mod;
if (!mca_recover_range(ms->pmsa_iip)) {
if (r13 != sos->prev_IA64_KR_CURRENT) {
msg = "inconsistent previous current and r13";
goto no_mod;
}
if ((r12 - r13) >= KERNEL_STACK_SIZE) {
msg = "inconsistent r12 and r13";
goto no_mod;
}
if ((ar_bspstore - r13) >= KERNEL_STACK_SIZE) {
msg = "inconsistent ar.bspstore and r13";
goto no_mod;
}
va.p = old_bspstore;
if (va.f.reg < 5) {
msg = "old_bspstore is in the wrong region";
goto no_mod;
}
if ((ar_bsp - r13) >= KERNEL_STACK_SIZE) {
msg = "inconsistent ar.bsp and r13";
goto no_mod;
}
size += (ia64_rse_skip_regs(old_bspstore, slots) - old_bspstore) * 8;
if (ar_bspstore + size > r12) {
msg = "no room for blocked state";
goto no_mod;
}
}
ia64_mca_modify_comm(previous_current);
......@@ -1443,7 +1491,7 @@ static struct irqaction mca_cpep_irqaction = {
* format most of the fields.
*/
static void
static void __cpuinit
format_mca_init_stack(void *mca_data, unsigned long offset,
const char *type, int cpu)
{
......@@ -1467,7 +1515,7 @@ format_mca_init_stack(void *mca_data, unsigned long offset,
/* Do per-CPU MCA-related initialization. */
void __devinit
void __cpuinit
ia64_mca_cpu_init(void *cpu_data)
{
void *pal_vaddr;
......
......@@ -6,6 +6,7 @@
* Copyright (C) Hidetoshi Seto (seto.hidetoshi@jp.fujitsu.com)
* Copyright (C) 2005 Silicon Graphics, Inc
* Copyright (C) 2005 Keith Owens <kaos@sgi.com>
* Copyright (C) 2006 Russ Anderson <rja@sgi.com>
*/
#include <linux/config.h>
#include <linux/types.h>
......@@ -121,11 +122,12 @@ mca_page_isolate(unsigned long paddr)
*/
void
mca_handler_bh(unsigned long paddr)
mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
{
printk(KERN_ERR
"OS_MCA: process [pid: %d](%s) encounters MCA (paddr=%lx)\n",
current->pid, current->comm, paddr);
printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, "
"iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n",
raw_smp_processor_id(), current->pid, current->uid,
iip, ipsr, paddr, current->comm);
spin_lock(&mca_bh_lock);
switch (mca_page_isolate(paddr)) {
......@@ -442,21 +444,26 @@ recover_from_read_error(slidx_table_t *slidx,
if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate))
return 0;
psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr);
psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr);
/*
* Check the privilege level of interrupted context.
* If it is user-mode, then terminate affected process.
*/
if (psr1->cpl != 0) {
pmsa = sos->pal_min_state;
if (psr1->cpl != 0 ||
((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) {
smei = peidx_bus_check(peidx, 0);
if (smei->valid.target_identifier) {
/*
* setup for resume to bottom half of MCA,
* "mca_handler_bhhook"
*/
pmsa = sos->pal_min_state;
/* pass to bhhook as 1st argument (gr8) */
/* pass to bhhook as argument (gr8, ...) */
pmsa->pmsa_gr[8-1] = smei->target_identifier;
pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
/* set interrupted return address (but no use) */
pmsa->pmsa_br0 = pmsa->pmsa_iip;
/* change resume address to bottom half */
......@@ -466,6 +473,7 @@ recover_from_read_error(slidx_table_t *slidx,
psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
psr2->cpl = 0;
psr2->ri = 0;
psr2->bn = 1;
psr2->i = 0;
return 1;
......
......@@ -111,3 +111,10 @@ typedef struct slidx_table {
slidx_foreach_entry(__pos, &((slidx)->sec)) { __count++; }\
__count; })
struct mca_table_entry {
int start_addr; /* location-relative starting address of MCA recoverable range */
int end_addr; /* location-relative ending address of MCA recoverable range */
};
extern const struct mca_table_entry *search_mca_tables (unsigned long addr);
extern int mca_recover_range(unsigned long);
......@@ -14,15 +14,12 @@
GLOBAL_ENTRY(mca_handler_bhhook)
invala // clear RSE ?
;;
cover
;;
clrrrb
;;
alloc r16=ar.pfs,0,2,1,0 // make a new frame
;;
alloc r16=ar.pfs,0,2,3,0 // make a new frame
mov ar.rsc=0
;;
mov r13=IA64_KR(CURRENT) // current task pointer
;;
mov r2=r13
......@@ -30,7 +27,6 @@ GLOBAL_ENTRY(mca_handler_bhhook)
addl r22=IA64_RBS_OFFSET,r2
;;
mov ar.bspstore=r22
;;
addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2
;;
adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
......@@ -40,12 +36,12 @@ GLOBAL_ENTRY(mca_handler_bhhook)
movl loc1=mca_handler_bh // recovery C function
;;
mov out0=r8 // poisoned address
mov out1=r9 // iip
mov out2=r10 // psr
mov b6=loc1
;;
mov loc1=rp
;;
ssm psr.i
;;
ssm psr.i | psr.ic
br.call.sptk.many rp=b6 // does not return ...
;;
mov ar.pfs=loc0
......@@ -53,5 +49,4 @@ GLOBAL_ENTRY(mca_handler_bhhook)
;;
mov r8=r0
br.ret.sptk.many rp
;;
END(mca_handler_bhhook)
......@@ -25,7 +25,7 @@
#include <asm/processor.h>
#include <asm/smp.h>
u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
EXPORT_SYMBOL(cpu_to_node_map);
cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
......
......@@ -115,7 +115,7 @@ ia64_patch_vtop (unsigned long start, unsigned long end)
ia64_srlz_i();
}
void
void __init
ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
{
static int first_time = 1;
......@@ -149,7 +149,7 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
ia64_srlz_i();
}
static void
static void __init
patch_fsyscall_table (unsigned long start, unsigned long end)
{
extern unsigned long fsyscall_table[NR_syscalls];
......@@ -166,7 +166,7 @@ patch_fsyscall_table (unsigned long start, unsigned long end)
ia64_srlz_i();
}
static void
static void __init
patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
{
extern char fsys_bubble_down[];
......@@ -184,7 +184,7 @@ patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
ia64_srlz_i();
}
void
void __init
ia64_patch_gate (void)
{
# define START(name) ((unsigned long) __start_gate_##name##_patchlist)
......
......@@ -130,8 +130,8 @@ EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
/*
* We use a special marker for the end of memory and it uses the extra (+1) slot
*/
struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
int num_rsvd_regions;
struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1] __initdata;
int num_rsvd_regions __initdata;
/*
......@@ -140,7 +140,7 @@ int num_rsvd_regions;
* caller-specified function is called with the memory ranges that remain after filtering.
* This routine does not assume the incoming segments are sorted.
*/
int
int __init
filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
{
unsigned long range_start, range_end, prev_start;
......@@ -176,7 +176,7 @@ filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
return 0;
}
static void
static void __init
sort_regions (struct rsvd_region *rsvd_region, int max)
{
int j;
......@@ -217,7 +217,7 @@ __initcall(register_memory);
* initrd, etc. There are currently %IA64_MAX_RSVD_REGIONS defined,
* see include/asm-ia64/meminit.h if you need to define more.
*/
void
void __init
reserve_memory (void)
{
int n = 0;
......@@ -269,7 +269,7 @@ reserve_memory (void)
* Grab the initrd start and end from the boot parameter struct given us by
* the boot loader.
*/
void
void __init
find_initrd (void)
{
#ifdef CONFIG_BLK_DEV_INITRD
......@@ -361,7 +361,7 @@ mark_bsp_online (void)
}
#ifdef CONFIG_SMP
static void
static void __init
check_for_logical_procs (void)
{
pal_logical_to_physical_t info;
......@@ -388,6 +388,14 @@ check_for_logical_procs (void)
}
#endif
static __initdata int nomca;
static __init int setup_nomca(char *s)
{
nomca = 1;
return 0;
}
early_param("nomca", setup_nomca);
void __init
setup_arch (char **cmdline_p)
{
......@@ -401,35 +409,15 @@ setup_arch (char **cmdline_p)
efi_init();
io_port_init();
parse_early_param();
#ifdef CONFIG_IA64_GENERIC
{
const char *mvec_name = strstr (*cmdline_p, "machvec=");
char str[64];
if (mvec_name) {
const char *end;
size_t len;
mvec_name += 8;
end = strchr (mvec_name, ' ');
if (end)
len = end - mvec_name;
else
len = strlen (mvec_name);
len = min(len, sizeof (str) - 1);
strncpy (str, mvec_name, len);
str[len] = '\0';
mvec_name = str;
} else
mvec_name = acpi_get_sysname();
machvec_init(mvec_name);
}
machvec_init(NULL);
#endif
if (early_console_setup(*cmdline_p) == 0)
mark_bsp_online();
parse_early_param();
#ifdef CONFIG_ACPI
/* Initialize the ACPI boot-time table parser */
acpi_table_init();
......@@ -492,7 +480,7 @@ setup_arch (char **cmdline_p)
#endif
/* enable IA-64 Machine Check Abort Handling unless disabled */
if (!strstr(saved_command_line, "nomca"))
if (!nomca)
ia64_mca_init();
platform_setup(cmdline_p);
......@@ -622,7 +610,7 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo
};
void
static void __cpuinit
identify_cpu (struct cpuinfo_ia64 *c)
{
union {
......@@ -699,7 +687,7 @@ setup_per_cpu_areas (void)
* In addition, the minimum of the i-cache stride sizes is calculated for
* "flush_icache_range()".
*/
static void
static void __cpuinit
get_max_cacheline_size (void)
{
unsigned long line_size, max = 1;
......@@ -762,10 +750,10 @@ get_max_cacheline_size (void)
* cpu_init() initializes state that is per-CPU. This function acts
* as a 'CPU state barrier', nothing should get across.
*/
void
void __cpuinit
cpu_init (void)
{
extern void __devinit ia64_mmu_init (void *);
extern void __cpuinit ia64_mmu_init (void *);
unsigned long num_phys_stacked;
pal_vm_info_2_u_t vmi;
unsigned int max_ctx;
......@@ -893,7 +881,7 @@ void sched_cacheflush(void)
ia64_sal_cache_flush(3);
}
void
void __init
check_bugs (void)
{
ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
......
......@@ -624,31 +624,7 @@ void __devinit smp_prepare_boot_cpu(void)
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
}
/*
* mt_info[] is a temporary store for all info returned by
* PAL_LOGICAL_TO_PHYSICAL, to be copied into cpuinfo_ia64 when the
* specific cpu comes.
*/
static struct {
__u32 socket_id;
__u16 core_id;
__u16 thread_id;
__u16 proc_fixed_addr;
__u8 valid;
} mt_info[NR_CPUS] __devinitdata;
#ifdef CONFIG_HOTPLUG_CPU
static inline void
remove_from_mtinfo(int cpu)
{
int i;
for_each_cpu(i)
if (mt_info[i].valid && mt_info[i].socket_id ==
cpu_data(cpu)->socket_id)
mt_info[i].valid = 0;
}
static inline void
clear_cpu_sibling_map(int cpu)
{
......@@ -678,12 +654,6 @@ remove_siblinginfo(int cpu)
/* remove it from all sibling map's */
clear_cpu_sibling_map(cpu);
/* if this cpu is the last in the core group, remove all its info
* from mt_info structure
*/
if (last)
remove_from_mtinfo(cpu);
}
extern void fixup_irqs(void);
......@@ -878,40 +848,6 @@ init_smp_config(void)
ia64_sal_strerror(sal_ret));
}
static inline int __devinit
check_for_mtinfo_index(void)
{
int i;
for_each_cpu(i)
if (!mt_info[i].valid)
return i;
return -1;
}
/*
* Search the mt_info to find out if this socket's cid/tid information is
* cached or not. If the socket exists, fill in the core_id and thread_id
* in cpuinfo
*/
static int __devinit
check_for_new_socket(__u16 logical_address, struct cpuinfo_ia64 *c)
{
int i;
__u32 sid = c->socket_id;
for_each_cpu(i) {
if (mt_info[i].valid && mt_info[i].proc_fixed_addr == logical_address
&& mt_info[i].socket_id == sid) {
c->core_id = mt_info[i].core_id;
c->thread_id = mt_info[i].thread_id;
return 1; /* not a new socket */
}
}
return 0;
}
/*
* identify_siblings(cpu) gets called from identify_cpu. This populates the
* information related to logical execution units in per_cpu_data structure.
......@@ -921,14 +857,12 @@ identify_siblings(struct cpuinfo_ia64 *c)
{
s64 status;
u16 pltid;
u64 proc_fixed_addr;
int count, i;
pal_logical_to_physical_t info;
if (smp_num_cpucores == 1 && smp_num_siblings == 1)
return;
if ((status = ia64_pal_logical_to_phys(0, &info)) != PAL_STATUS_SUCCESS) {
if ((status = ia64_pal_logical_to_phys(-1, &info)) != PAL_STATUS_SUCCESS) {
printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n",
status);
return;
......@@ -937,47 +871,12 @@ identify_siblings(struct cpuinfo_ia64 *c)
printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status);
return;
}
if ((status = ia64_pal_fixed_addr(&proc_fixed_addr)) != PAL_STATUS_SUCCESS) {
printk(KERN_ERR "ia64_pal_fixed_addr failed with %ld\n", status);
return;
}
c->socket_id = (pltid << 8) | info.overview_ppid;
c->cores_per_socket = info.overview_cpp;
c->threads_per_core = info.overview_tpc;
count = c->num_log = info.overview_num_log;
c->num_log = info.overview_num_log;
/* If the thread and core id information is already cached, then
* we will simply update cpu_info and return. Otherwise, we will
* do the PAL calls and cache core and thread id's of all the siblings.
*/
if (check_for_new_socket(proc_fixed_addr, c))
return;
for (i = 0; i < count; i++) {
int index;
if (i && (status = ia64_pal_logical_to_phys(i, &info))
!= PAL_STATUS_SUCCESS) {
printk(KERN_ERR "ia64_pal_logical_to_phys failed"
" with %ld\n", status);
return;
}
if (info.log2_la == proc_fixed_addr) {
c->core_id = info.log1_cid;
c->thread_id = info.log1_tid;
}
index = check_for_mtinfo_index();
/* We will not do the mt_info caching optimization in this case.
*/
if (index < 0)
continue;
mt_info[index].valid = 1;
mt_info[index].socket_id = c->socket_id;
mt_info[index].core_id = info.log1_cid;
mt_info[index].thread_id = info.log1_tid;
mt_info[index].proc_fixed_addr = info.log2_la;
}
c->core_id = info.log1_cid;
c->thread_id = info.log1_tid;
}
......@@ -70,34 +70,9 @@ SECTIONS
__stop___ex_table = .;
}
.data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
{
__start___vtop_patchlist = .;
*(.data.patch.vtop)
__end___vtop_patchlist = .;
}
.data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET)
{
__start___mckinley_e9_bundles = .;
*(.data.patch.mckinley_e9)
__end___mckinley_e9_bundles = .;
}
/* Global data */
_data = .;
#if defined(CONFIG_IA64_GENERIC)
/* Machine Vector */
. = ALIGN(16);
.machvec : AT(ADDR(.machvec) - LOAD_OFFSET)
{
machvec_start = .;
*(.machvec)
machvec_end = .;
}
#endif
/* Unwind info & table: */
. = ALIGN(8);
.IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET)
......@@ -154,6 +129,41 @@ SECTIONS
*(.initcall7.init)
__initcall_end = .;
}
/* MCA table */
. = ALIGN(16);
__mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET)
{
__start___mca_table = .;
*(__mca_table)
__stop___mca_table = .;
}
.data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
{
__start___vtop_patchlist = .;
*(.data.patch.vtop)
__end___vtop_patchlist = .;
}
.data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET)
{
__start___mckinley_e9_bundles = .;
*(.data.patch.mckinley_e9)
__end___mckinley_e9_bundles = .;
}
#if defined(CONFIG_IA64_GENERIC)
/* Machine Vector */
. = ALIGN(16);
.machvec : AT(ADDR(.machvec) - LOAD_OFFSET)
{
machvec_start = .;
*(.machvec)
machvec_end = .;
}
#endif
__con_initcall_start = .;
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET)
{ *(.con_initcall.init) }
......
......@@ -97,7 +97,7 @@ find_max_pfn (unsigned long start, unsigned long end, void *arg)
* Find a place to put the bootmap and return its starting address in
* bootmap_start. This address must be page-aligned.
*/
int
static int __init
find_bootmap_location (unsigned long start, unsigned long end, void *arg)
{
unsigned long needed = *(unsigned long *)arg;
......@@ -141,7 +141,7 @@ find_bootmap_location (unsigned long start, unsigned long end, void *arg)
* Walk the EFI memory map and find usable memory for the system, taking
* into account reserved areas.
*/
void
void __init
find_memory (void)
{
unsigned long bootmap_size;
......@@ -176,7 +176,7 @@ find_memory (void)
*
* Allocate and setup per-cpu data areas.
*/
void *
void * __cpuinit
per_cpu_init (void)
{
void *cpu_data;
......@@ -228,7 +228,7 @@ count_dma_pages (u64 start, u64 end, void *arg)
* Set up the page tables.
*/
void
void __init
paging_init (void)
{
unsigned long max_dma;
......
......@@ -525,7 +525,7 @@ void __init find_memory(void)
* find_pernode_space() does most of this already, we just need to set
* local_per_cpu_offset
*/
void *per_cpu_init(void)
void __cpuinit *per_cpu_init(void)
{
int cpu;
static int first_time = 1;
......
......@@ -113,8 +113,7 @@ void hugetlb_free_pgd_range(struct mmu_gather **tlb,
unsigned long floor, unsigned long ceiling)
{
/*
* This is called only when is_hugepage_only_range(addr,),
* and it follows that is_hugepage_only_range(end,) also.
* This is called to free hugetlb page tables.
*
* The offset of these addresses from the base of the hugetlb
* region must be scaled down by HPAGE_SIZE/PAGE_SIZE so that
......@@ -126,9 +125,9 @@ void hugetlb_free_pgd_range(struct mmu_gather **tlb,
addr = htlbpage_to_page(addr);
end = htlbpage_to_page(end);
if (is_hugepage_only_range(tlb->mm, floor, HPAGE_SIZE))
if (REGION_NUMBER(floor) == RGN_HPAGE)
floor = htlbpage_to_page(floor);
if (is_hugepage_only_range(tlb->mm, ceiling, HPAGE_SIZE))
if (REGION_NUMBER(ceiling) == RGN_HPAGE)
ceiling = htlbpage_to_page(ceiling);
free_pgd_range(tlb, addr, end, floor, ceiling);
......
......@@ -206,7 +206,7 @@ free_initmem (void)
(__init_end - __init_begin) >> 10);
}
void
void __init
free_initrd_mem (unsigned long start, unsigned long end)
{
struct page *page;
......@@ -261,7 +261,7 @@ free_initrd_mem (unsigned long start, unsigned long end)
/*
* This installs a clean page in the kernel's page table.
*/
struct page *
static struct page * __init
put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
{
pgd_t *pgd;
......@@ -294,7 +294,7 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
return page;
}
static void
static void __init
setup_gate (void)
{
struct page *page;
......@@ -411,7 +411,7 @@ ia64_mmu_init (void *my_cpu_data)
#ifdef CONFIG_VIRTUAL_MEM_MAP
int
int __init
create_mem_map_page_table (u64 start, u64 end, void *arg)
{
unsigned long address, start_page, end_page;
......@@ -519,7 +519,7 @@ ia64_pfn_valid (unsigned long pfn)
}
EXPORT_SYMBOL(ia64_pfn_valid);
int
int __init
find_largest_hole (u64 start, u64 end, void *arg)
{
u64 *max_gap = arg;
......@@ -535,7 +535,7 @@ find_largest_hole (u64 start, u64 end, void *arg)
}
#endif /* CONFIG_VIRTUAL_MEM_MAP */
static int
static int __init
count_reserved_pages (u64 start, u64 end, void *arg)
{
unsigned long num_reserved = 0;
......@@ -556,7 +556,7 @@ count_reserved_pages (u64 start, u64 end, void *arg)
* purposes.
*/
static int nolwsys;
static int nolwsys __initdata;
static int __init
nolwsys_setup (char *s)
......@@ -567,7 +567,7 @@ nolwsys_setup (char *s)
__setup("nolwsys", nolwsys_setup);
void
void __init
mem_init (void)
{
long reserved_pages, codesize, datasize, initsize;
......
......@@ -13,6 +13,8 @@
#include <asm/sn/sn_feature_sets.h>
#include <asm/sn/geo.h>
#include <asm/sn/io.h>
#include <asm/sn/l1.h>
#include <asm/sn/module.h>
#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
......@@ -710,9 +712,36 @@ cnodeid_get_geoid(cnodeid_t cnode)
return hubdev->hdi_geoid;
}
void sn_generate_path(struct pci_bus *pci_bus, char *address)
{
nasid_t nasid;
cnodeid_t cnode;
geoid_t geoid;
moduleid_t moduleid;
u16 bricktype;
nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
cnode = nasid_to_cnodeid(nasid);
geoid = cnodeid_get_geoid(cnode);
moduleid = geo_module(geoid);
sprintf(address, "module_%c%c%c%c%.2d",
'0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)),
'0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)),
'0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)),
MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid));
/* Tollhouse requires slot id to be displayed */
bricktype = MODULE_GET_BTYPE(moduleid);
if ((bricktype == L1_BRICKTYPE_191010) ||
(bricktype == L1_BRICKTYPE_1932))
sprintf(address, "%s^%d", address, geo_slot(geoid));
}
subsys_initcall(sn_pci_init);
EXPORT_SYMBOL(sn_pci_fixup_slot);
EXPORT_SYMBOL(sn_pci_unfixup_slot);
EXPORT_SYMBOL(sn_pci_controller_fixup);
EXPORT_SYMBOL(sn_bus_store_sysdata);
EXPORT_SYMBOL(sn_bus_free_sysdata);
EXPORT_SYMBOL(sn_generate_path);
......@@ -350,9 +350,6 @@ static void force_interrupt(int irq)
static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
{
u64 regval;
int irr_reg_num;
int irr_bit;
u64 irr_reg;
struct pcidev_info *pcidev_info;
struct pcibus_info *pcibus_info;
......@@ -373,23 +370,7 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
pdi_pcibus_info;
regval = pcireg_intr_status_get(pcibus_info);
irr_reg_num = irq_to_vector(irq) / 64;
irr_bit = irq_to_vector(irq) % 64;
switch (irr_reg_num) {
case 0:
irr_reg = ia64_getreg(_IA64_REG_CR_IRR0);
break;
case 1:
irr_reg = ia64_getreg(_IA64_REG_CR_IRR1);
break;
case 2:
irr_reg = ia64_getreg(_IA64_REG_CR_IRR2);
break;
case 3:
irr_reg = ia64_getreg(_IA64_REG_CR_IRR3);
break;
}
if (!test_bit(irr_bit, &irr_reg)) {
if (!ia64_get_irr(irq_to_vector(irq))) {
if (!test_bit(irq, pda->sn_in_service_ivecs)) {
regval &= 0xff;
if (sn_irq_info->irq_int_bit & regval &
......
......@@ -369,9 +369,15 @@ static void tio_corelet_reset(nasid_t nasid, int corelet)
static int is_fpga_tio(int nasid, int *bt)
{
int ioboard_type;
u16 ioboard_type;
s64 rc;
ioboard_type = ia64_sn_sysctl_ioboard_get(nasid);
rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type);
if (rc) {
printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n",
rc);
return 0;
}
switch (ioboard_type) {
case L1_BRICKTYPE_SA:
......
......@@ -74,6 +74,22 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
return (int)ret_stuff.v0;
}
u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus)
{
s64 rc;
u16 ioboard;
nasid_t nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard);
if (rc) {
printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n",
rc);
return 0;
}
return ioboard;
}
/*
* PCI Bridge Error interrupt handler. Gets invoked whenever a PCI
* bridge sends an error interrupt.
......@@ -255,3 +271,4 @@ pcibr_init_provider(void)
EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable);
EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable);
EXPORT_SYMBOL_GPL(sn_ioboard_to_pci_bus);
......@@ -111,7 +111,11 @@ extern int additional_cpus;
#ifdef CONFIG_ACPI_NUMA
/* Proximity bitmap length; _PXM is at most 255 (8 bit)*/
#ifdef CONFIG_IA64_NR_NODES
#define MAX_PXM_DOMAINS CONFIG_IA64_NR_NODES
#else
#define MAX_PXM_DOMAINS (256)
#endif
extern int __devinitdata pxm_to_nid_map[MAX_PXM_DOMAINS];
extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
#endif
......
......@@ -50,6 +50,17 @@
.xdata4 "__ex_table", 99f-., y-.+4; \
[99:] x
/*
* Tag MCA recoverable instruction ranges.
*/
.section "__mca_table", "a" // declare section & section attributes
.previous
# define MCA_RECOVER_RANGE(y) \
.xdata4 "__mca_table", y-., 99f-.; \
[99:]
/*
* Mark instructions that need a load of a virtual address patched to be
* a load of a physical address. We use this either in critical performance
......
......@@ -2,7 +2,6 @@
#define _ASM_IA64_MACHVEC_DIG_h
extern ia64_mv_setup_t dig_setup;
extern ia64_mv_irq_init_t dig_irq_init;
/*
* This stuff has dual use!
......@@ -13,6 +12,5 @@ extern ia64_mv_irq_init_t dig_irq_init;
*/
#define platform_name "dig"
#define platform_setup dig_setup
#define platform_irq_init dig_irq_init
#endif /* _ASM_IA64_MACHVEC_DIG_h */
......@@ -23,7 +23,7 @@
#include <asm/mmzone.h>
extern u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
extern u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
/* Stuff below this line could be architecture independent */
......
......@@ -3,13 +3,18 @@
#ifdef CONFIG_IA64_DIG
/* Max 8 Nodes */
#define NODES_SHIFT 3
# define NODES_SHIFT 3
#elif defined(CONFIG_IA64_HP_ZX1) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
/* Max 32 Nodes */
#define NODES_SHIFT 5
# define NODES_SHIFT 5
#elif defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
/* Max 256 Nodes */
#define NODES_SHIFT 8
# if CONFIG_IA64_NR_NODES == 256
# define NODES_SHIFT 8
# elif CONFIG_IA64_NR_NODES <= 512
# define NODES_SHIFT 9
# elif CONFIG_IA64_NR_NODES <= 1024
# define NODES_SHIFT 10
# endif
#endif
#endif /* _ASM_MAX_NUMNODES_H */
......@@ -149,7 +149,7 @@ typedef union ia64_va {
| (REGION_OFFSET(x) >> (HPAGE_SHIFT-PAGE_SHIFT)))
# define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
# define is_hugepage_only_range(mm, addr, len) \
(REGION_NUMBER(addr) == RGN_HPAGE && \
(REGION_NUMBER(addr) == RGN_HPAGE || \
REGION_NUMBER((addr)+(len)-1) == RGN_HPAGE)
extern unsigned int hpage_shift;
#endif
......
......@@ -1640,8 +1640,7 @@ ia64_pal_logical_to_phys(u64 proc_number, pal_logical_to_physical_t *mapping)
if (iprv.status == PAL_STATUS_SUCCESS)
{
if (proc_number == 0)
mapping->overview.overview_data = iprv.v0;
mapping->overview.overview_data = iprv.v0;
mapping->ppli1.ppli1_data = iprv.v1;
mapping->ppli2.ppli2_data = iprv.v2;
}
......
......@@ -181,7 +181,6 @@ DECLARE_PER_CPU(struct cpuinfo_ia64, cpu_info);
#define local_cpu_data (&__ia64_per_cpu_var(cpu_info))
#define cpu_data(cpu) (&per_cpu(cpu_info, cpu))
extern void identify_cpu (struct cpuinfo_ia64 *);
extern void print_cpu_info (struct cpuinfo_ia64 *);
typedef struct {
......
......@@ -34,6 +34,8 @@
#define L1_BRICKTYPE_IA 0x6b /* k */
#define L1_BRICKTYPE_ATHENA 0x2b /* + */
#define L1_BRICKTYPE_DAYTONA 0x7a /* z */
#define L1_BRICKTYPE_1932 0x2c /* . */
#define L1_BRICKTYPE_191010 0x2e /* , */
/* board type response codes */
#define L1_BOARDTYPE_IP69 0x0100 /* CA */
......@@ -46,5 +48,4 @@
#define L1_BOARDTYPE_DAYTONA 0x0800 /* AD */
#define L1_BOARDTYPE_INVAL (-1) /* invalid brick type */
#endif /* _ASM_IA64_SN_L1_H */
......@@ -144,4 +144,5 @@ extern int sal_pcibr_slot_enable(struct pcibus_info *soft, int device,
void *resp);
extern int sal_pcibr_slot_disable(struct pcibus_info *soft, int device,
int action, void *resp);
extern u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus);
#endif
......@@ -76,6 +76,7 @@ extern void sn_pci_controller_fixup(int segment, int busnum,
struct pci_bus *bus);
extern void sn_bus_store_sysdata(struct pci_dev *dev);
extern void sn_bus_free_sysdata(void);
extern void sn_generate_path(struct pci_bus *pci_bus, char *address);
extern void sn_pci_fixup_slot(struct pci_dev *dev);
extern void sn_pci_unfixup_slot(struct pci_dev *dev);
extern void sn_irq_lh_init(void);
......
......@@ -30,8 +30,7 @@ extern int sn_prom_feature_available(int id);
#define PRF_PAL_CACHE_FLUSH_SAFE 0
#define PRF_DEVICE_FLUSH_LIST 1
#define PRF_HOTPLUG_SUPPORT 2
/* --------------------- OS Features -------------------------------*/
......
......@@ -907,18 +907,22 @@ ia64_sn_sysctl_tio_clock_reset(nasid_t nasid)
/*
* Get the associated ioboard type for a given nasid.
*/
static inline int
ia64_sn_sysctl_ioboard_get(nasid_t nasid)
static inline s64
ia64_sn_sysctl_ioboard_get(nasid_t nasid, u16 *ioboard)
{
struct ia64_sal_retval rv;
SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD,
nasid, 0, 0, 0, 0, 0);
if (rv.v0 != 0)
return (int)rv.v0;
if (rv.v1 != 0)
return (int)rv.v1;
return 0;
struct ia64_sal_retval isrv;
SAL_CALL_REENTRANT(isrv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD,
nasid, 0, 0, 0, 0, 0);
if (isrv.v0 != 0) {
*ioboard = isrv.v0;
return isrv.status;
}
if (isrv.v1 != 0) {
*ioboard = isrv.v1;
return isrv.status;
}
return isrv.status;
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册