aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-11 15:51:40 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-11 15:51:40 -0700
commit357d596bd552ad157a906289ab13ea6ba7e66e3d (patch)
tree78b8f6bc2781af2e95a6cf2b20a06dfe8bb04e5c /include
parente6c69bd39199656a8bbd0569edaff60574ff9cac (diff)
parentd67eb16f5d444fb6d173bcec889ddb2066c0fa0c (diff)
Merge branch 'release' of master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6
Diffstat (limited to 'include')
-rw-r--r--include/asm-ia64/mca.h102
-rw-r--r--include/asm-ia64/mca_asm.h125
-rw-r--r--include/asm-ia64/ptrace.h2
-rw-r--r--include/asm-ia64/sn/sn_feature_sets.h57
-rw-r--r--include/asm-ia64/sn/sn_sal.h36
-rw-r--r--include/asm-ia64/thread_info.h2
-rw-r--r--include/asm-ia64/unwind.h7
-rw-r--r--include/linux/sched.h2
8 files changed, 180 insertions, 153 deletions
diff --git a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h
index 149ad011845..97a28b8b2dd 100644
--- a/include/asm-ia64/mca.h
+++ b/include/asm-ia64/mca.h
@@ -11,8 +11,6 @@
#ifndef _ASM_IA64_MCA_H
#define _ASM_IA64_MCA_H
-#define IA64_MCA_STACK_SIZE 8192
-
#if !defined(__ASSEMBLY__)
#include <linux/interrupt.h>
@@ -48,7 +46,8 @@ typedef union cmcv_reg_u {
enum {
IA64_MCA_RENDEZ_CHECKIN_NOTDONE = 0x0,
- IA64_MCA_RENDEZ_CHECKIN_DONE = 0x1
+ IA64_MCA_RENDEZ_CHECKIN_DONE = 0x1,
+ IA64_MCA_RENDEZ_CHECKIN_INIT = 0x2,
};
/* Information maintained by the MC infrastructure */
@@ -63,18 +62,42 @@ typedef struct ia64_mc_info_s {
} ia64_mc_info_t;
-typedef struct ia64_mca_sal_to_os_state_s {
- u64 imsto_os_gp; /* GP of the os registered with the SAL */
- u64 imsto_pal_proc; /* PAL_PROC entry point - physical addr */
- u64 imsto_sal_proc; /* SAL_PROC entry point - physical addr */
- u64 imsto_sal_gp; /* GP of the SAL - physical */
- u64 imsto_rendez_state; /* Rendez state information */
- u64 imsto_sal_check_ra; /* Return address in SAL_CHECK while going
- * back to SAL from OS after MCA handling.
- */
- u64 pal_min_state; /* from PAL in r17 */
- u64 proc_state_param; /* from PAL in r18. See SDV 2:268 11.3.2.1 */
-} ia64_mca_sal_to_os_state_t;
+/* Handover state from SAL to OS and vice versa, for both MCA and INIT events.
+ * Besides the handover state, it also contains some saved registers from the
+ * time of the event.
+ * Note: mca_asm.S depends on the precise layout of this structure.
+ */
+
+struct ia64_sal_os_state {
+ /* SAL to OS, must be at offset 0 */
+ u64 os_gp; /* GP of the os registered with the SAL, physical */
+ u64 pal_proc; /* PAL_PROC entry point, physical */
+ u64 sal_proc; /* SAL_PROC entry point, physical */
+ u64 rv_rc; /* MCA - Rendezvous state, INIT - reason code */
+ u64 proc_state_param; /* from R18 */
+ u64 monarch; /* 1 for a monarch event, 0 for a slave */
+ /* common, must follow SAL to OS */
+ u64 sal_ra; /* Return address in SAL, physical */
+ u64 sal_gp; /* GP of the SAL - physical */
+ pal_min_state_area_t *pal_min_state; /* from R17. physical in asm, virtual in C */
+ u64 prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */
+ struct task_struct *prev_task; /* previous task, NULL if it is not useful */
+ /* Some interrupt registers are not saved in minstate, pt_regs or
+ * switch_stack. Because MCA/INIT can occur when interrupts are
+ * disabled, we need to save the additional interrupt registers over
+ * MCA/INIT and resume.
+ */
+ u64 isr;
+ u64 ifa;
+ u64 itir;
+ u64 iipa;
+ u64 iim;
+ u64 iha;
+ /* OS to SAL, must follow common */
+ u64 os_status; /* OS status to SAL, enum below */
+ u64 context; /* 0 if return to same context
+ 1 if return to new context */
+};
enum {
IA64_MCA_CORRECTED = 0x0, /* Error has been corrected by OS_MCA */
@@ -84,35 +107,21 @@ enum {
};
enum {
+ IA64_INIT_RESUME = 0x0, /* Resume after return from INIT */
+ IA64_INIT_WARM_BOOT = -1, /* Warm boot of the system need from SAL */
+};
+
+enum {
IA64_MCA_SAME_CONTEXT = 0x0, /* SAL to return to same context */
IA64_MCA_NEW_CONTEXT = -1 /* SAL to return to new context */
};
-typedef struct ia64_mca_os_to_sal_state_s {
- u64 imots_os_status; /* OS status to SAL as to what happened
- * with the MCA handling.
- */
- u64 imots_sal_gp; /* GP of the SAL - physical */
- u64 imots_context; /* 0 if return to same context
- 1 if return to new context */
- u64 *imots_new_min_state; /* Pointer to structure containing
- * new values of registers in the min state
- * save area.
- */
- u64 imots_sal_check_ra; /* Return address in SAL_CHECK while going
- * back to SAL from OS after MCA handling.
- */
-} ia64_mca_os_to_sal_state_t;
-
/* Per-CPU MCA state that is too big for normal per-CPU variables. */
struct ia64_mca_cpu {
- u64 stack[IA64_MCA_STACK_SIZE/8]; /* MCA memory-stack */
- u64 proc_state_dump[512];
- u64 stackframe[32];
- u64 rbstore[IA64_MCA_STACK_SIZE/8]; /* MCA reg.-backing store */
+ u64 mca_stack[KERNEL_STACK_SIZE/8];
u64 init_stack[KERNEL_STACK_SIZE/8];
-} __attribute__ ((aligned(16)));
+};
/* Array of physical addresses of each CPU's MCA area. */
extern unsigned long __per_cpu_mca[NR_CPUS];
@@ -121,12 +130,29 @@ extern void ia64_mca_init(void);
extern void ia64_mca_cpu_init(void *);
extern void ia64_os_mca_dispatch(void);
extern void ia64_os_mca_dispatch_end(void);
-extern void ia64_mca_ucmc_handler(void);
+extern void ia64_mca_ucmc_handler(struct pt_regs *, struct ia64_sal_os_state *);
+extern void ia64_init_handler(struct pt_regs *,
+ struct switch_stack *,
+ struct ia64_sal_os_state *);
extern void ia64_monarch_init_handler(void);
extern void ia64_slave_init_handler(void);
extern void ia64_mca_cmc_vector_setup(void);
-extern int ia64_reg_MCA_extension(void*);
+extern int ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *));
extern void ia64_unreg_MCA_extension(void);
+extern u64 ia64_get_rnat(u64 *);
+
+#else /* __ASSEMBLY__ */
+
+#define IA64_MCA_CORRECTED 0x0 /* Error has been corrected by OS_MCA */
+#define IA64_MCA_WARM_BOOT -1 /* Warm boot of the system need from SAL */
+#define IA64_MCA_COLD_BOOT -2 /* Cold boot of the system need from SAL */
+#define IA64_MCA_HALT -3 /* System to be halted by SAL */
+
+#define IA64_INIT_RESUME 0x0 /* Resume after return from INIT */
+#define IA64_INIT_WARM_BOOT -1 /* Warm boot of the system need from SAL */
+
+#define IA64_MCA_SAME_CONTEXT 0x0 /* SAL to return to same context */
+#define IA64_MCA_NEW_CONTEXT -1 /* SAL to return to new context */
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_MCA_H */
diff --git a/include/asm-ia64/mca_asm.h b/include/asm-ia64/mca_asm.h
index 836953e0f91..27c9203d8ce 100644
--- a/include/asm-ia64/mca_asm.h
+++ b/include/asm-ia64/mca_asm.h
@@ -8,6 +8,8 @@
* Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
* Copyright (C) 2002 Intel Corp.
* Copyright (C) 2002 Jenna Hall <jenna.s.hall@intel.com>
+ * Copyright (C) 2005 Silicon Graphics, Inc
+ * Copyright (C) 2005 Keith Owens <kaos@sgi.com>
*/
#ifndef _ASM_IA64_MCA_ASM_H
#define _ASM_IA64_MCA_ASM_H
@@ -207,106 +209,33 @@
;;
/*
- * The following offsets capture the order in which the
- * RSE related registers from the old context are
- * saved onto the new stack frame.
+ * The MCA and INIT stacks in struct ia64_mca_cpu look like normal kernel
+ * stacks, except that the SAL/OS state and a switch_stack are stored near the
+ * top of the MCA/INIT stack. To support concurrent entry to MCA or INIT, as
+ * well as MCA over INIT, each event needs its own SAL/OS state. All entries
+ * are 16 byte aligned.
*
- * +-----------------------+
- * |NDIRTY [BSP - BSPSTORE]|
- * +-----------------------+
- * | RNAT |
- * +-----------------------+
- * | BSPSTORE |
- * +-----------------------+
- * | IFS |
- * +-----------------------+
- * | PFS |
- * +-----------------------+
- * | RSC |
- * +-----------------------+ <-------- Bottom of new stack frame
+ * +---------------------------+
+ * | pt_regs |
+ * +---------------------------+
+ * | switch_stack |
+ * +---------------------------+
+ * | SAL/OS state |
+ * +---------------------------+
+ * | 16 byte scratch area |
+ * +---------------------------+ <-------- SP at start of C MCA handler
+ * | ..... |
+ * +---------------------------+
+ * | RBS for MCA/INIT handler |
+ * +---------------------------+
+ * | struct task for MCA/INIT |
+ * +---------------------------+ <-------- Bottom of MCA/INIT stack
*/
-#define rse_rsc_offset 0
-#define rse_pfs_offset (rse_rsc_offset+0x08)
-#define rse_ifs_offset (rse_pfs_offset+0x08)
-#define rse_bspstore_offset (rse_ifs_offset+0x08)
-#define rse_rnat_offset (rse_bspstore_offset+0x08)
-#define rse_ndirty_offset (rse_rnat_offset+0x08)
-/*
- * rse_switch_context
- *
- * 1. Save old RSC onto the new stack frame
- * 2. Save PFS onto new stack frame
- * 3. Cover the old frame and start a new frame.
- * 4. Save IFS onto new stack frame
- * 5. Save the old BSPSTORE on the new stack frame
- * 6. Save the old RNAT on the new stack frame
- * 7. Write BSPSTORE with the new backing store pointer
- * 8. Read and save the new BSP to calculate the #dirty registers
- * NOTE: Look at pages 11-10, 11-11 in PRM Vol 2
- */
-#define rse_switch_context(temp,p_stackframe,p_bspstore) \
- ;; \
- mov temp=ar.rsc;; \
- st8 [p_stackframe]=temp,8;; \
- mov temp=ar.pfs;; \
- st8 [p_stackframe]=temp,8; \
- cover ;; \
- mov temp=cr.ifs;; \
- st8 [p_stackframe]=temp,8;; \
- mov temp=ar.bspstore;; \
- st8 [p_stackframe]=temp,8;; \
- mov temp=ar.rnat;; \
- st8 [p_stackframe]=temp,8; \
- mov ar.bspstore=p_bspstore;; \
- mov temp=ar.bsp;; \
- sub temp=temp,p_bspstore;; \
- st8 [p_stackframe]=temp,8;;
-
-/*
- * rse_return_context
- * 1. Allocate a zero-sized frame
- * 2. Store the number of dirty registers RSC.loadrs field
- * 3. Issue a loadrs to insure that any registers from the interrupted
- * context which were saved on the new stack frame have been loaded
- * back into the stacked registers
- * 4. Restore BSPSTORE
- * 5. Restore RNAT
- * 6. Restore PFS
- * 7. Restore IFS
- * 8. Restore RSC
- * 9. Issue an RFI
- */
-#define rse_return_context(psr_mask_reg,temp,p_stackframe) \
- ;; \
- alloc temp=ar.pfs,0,0,0,0; \
- add p_stackframe=rse_ndirty_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- shl temp=temp,16;; \
- mov ar.rsc=temp;; \
- loadrs;; \
- add p_stackframe=-rse_ndirty_offset+rse_bspstore_offset,p_stackframe;;\
- ld8 temp=[p_stackframe];; \
- mov ar.bspstore=temp;; \
- add p_stackframe=-rse_bspstore_offset+rse_rnat_offset,p_stackframe;;\
- ld8 temp=[p_stackframe];; \
- mov ar.rnat=temp;; \
- add p_stackframe=-rse_rnat_offset+rse_pfs_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- mov ar.pfs=temp;; \
- add p_stackframe=-rse_pfs_offset+rse_ifs_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- mov cr.ifs=temp;; \
- add p_stackframe=-rse_ifs_offset+rse_rsc_offset,p_stackframe;; \
- ld8 temp=[p_stackframe];; \
- mov ar.rsc=temp ; \
- mov temp=psr;; \
- or temp=temp,psr_mask_reg;; \
- mov cr.ipsr=temp;; \
- mov temp=ip;; \
- add temp=0x30,temp;; \
- mov cr.iip=temp;; \
- srlz.i;; \
- rfi;;
+#define ALIGN16(x) ((x)&~15)
+#define MCA_PT_REGS_OFFSET ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE)
+#define MCA_SWITCH_STACK_OFFSET ALIGN16(MCA_PT_REGS_OFFSET-IA64_SWITCH_STACK_SIZE)
+#define MCA_SOS_OFFSET ALIGN16(MCA_SWITCH_STACK_OFFSET-IA64_SAL_OS_STATE_SIZE)
+#define MCA_SP_OFFSET ALIGN16(MCA_SOS_OFFSET-16)
#endif /* _ASM_IA64_MCA_ASM_H */
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
index c8766def9ee..fc544929ac3 100644
--- a/include/asm-ia64/ptrace.h
+++ b/include/asm-ia64/ptrace.h
@@ -119,7 +119,7 @@ struct pt_regs {
unsigned long ar_unat; /* interrupted task's NaT register (preserved) */
unsigned long ar_pfs; /* prev function state */
unsigned long ar_rsc; /* RSE configuration */
- /* The following two are valid only if cr_ipsr.cpl > 0: */
+ /* The following two are valid only if cr_ipsr.cpl > 0 || ti->flags & _TIF_MCA_INIT */
unsigned long ar_rnat; /* RSE NaT */
unsigned long ar_bspstore; /* RSE bspstore */
diff --git a/include/asm-ia64/sn/sn_feature_sets.h b/include/asm-ia64/sn/sn_feature_sets.h
new file mode 100644
index 00000000000..e68a80853d5
--- /dev/null
+++ b/include/asm-ia64/sn/sn_feature_sets.h
@@ -0,0 +1,57 @@
+#ifndef _ASM_IA64_SN_FEATURE_SETS_H
+#define _ASM_IA64_SN_FEATURE_SETS_H
+
+/*
+ * SN PROM Features
+ *
+ * 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) 2005 Silicon Graphics, Inc. All rights reserved.
+ */
+
+
+#include <asm/types.h>
+#include <asm/bitops.h>
+
+/* --------------------- PROM Features -----------------------------*/
+extern int sn_prom_feature_available(int id);
+
+#define MAX_PROM_FEATURE_SETS 2
+
+/*
+ * The following defines features that may or may not be supported by the
+ * current PROM. The OS uses sn_prom_feature_available(feature) to test for
+ * the presence of a PROM feature. Down rev (old) PROMs will always test
+ * "false" for new features.
+ *
+ * Use:
+ * if (sn_prom_feature_available(PRF_FEATURE_XXX))
+ * ...
+ */
+
+/*
+ * Example: feature XXX
+ */
+#define PRF_FEATURE_XXX 0
+
+
+
+/* --------------------- OS Features -------------------------------*/
+
+/*
+ * The following defines OS features that are optionally present in
+ * the operating system.
+ * During boot, PROM is notified of these features via a series of calls:
+ *
+ * ia64_sn_set_os_feature(feature1);
+ *
+ * Once enabled, a feature cannot be disabled.
+ *
+ * By default, features are disabled unless explicitly enabled.
+ */
+#define OSF_MCA_SLV_TO_OS_INIT_SLV 0
+#define OSF_FEAT_LOG_SBES 1
+
+#endif /* _ASM_IA64_SN_FEATURE_SETS_H */
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index e67825ad193..fea35b33d4e 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -80,6 +80,9 @@
#define SN_SAL_RESERVED_DO_NOT_USE 0x02000062
#define SN_SAL_IOIF_GET_PCI_TOPOLOGY 0x02000064
+#define SN_SAL_GET_PROM_FEATURE_SET 0x02000065
+#define SN_SAL_SET_OS_FEATURE_SET 0x02000066
+
/*
* Service-specific constants
*/
@@ -118,8 +121,8 @@
/*
* Error Handling Features
*/
-#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV 0x1
-#define SAL_ERR_FEAT_LOG_SBES 0x2
+#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV 0x1 // obsolete
+#define SAL_ERR_FEAT_LOG_SBES 0x2 // obsolete
#define SAL_ERR_FEAT_MFR_OVERRIDE 0x4
#define SAL_ERR_FEAT_SBE_THRESHOLD 0xffff0000
@@ -152,12 +155,6 @@ sn_sal_rev(void)
}
/*
- * Specify the minimum PROM revsion required for this kernel.
- * Note that they're stored in hex format...
- */
-#define SN_SAL_MIN_VERSION 0x0404
-
-/*
* Returns the master console nasid, if the call fails, return an illegal
* value.
*/
@@ -336,7 +333,7 @@ ia64_sn_plat_cpei_handler(void)
}
/*
- * Set Error Handling Features
+ * Set Error Handling Features (Obsolete)
*/
static inline u64
ia64_sn_plat_set_error_handling_features(void)
@@ -1052,4 +1049,25 @@ ia64_sn_is_fake_prom(void)
return (rv.status == 0);
}
+static inline int
+ia64_sn_get_prom_feature_set(int set, unsigned long *feature_set)
+{
+ struct ia64_sal_retval rv;
+
+ SAL_CALL_NOLOCK(rv, SN_SAL_GET_PROM_FEATURE_SET, set, 0, 0, 0, 0, 0, 0);
+ if (rv.status != 0)
+ return rv.status;
+ *feature_set = rv.v0;
+ return 0;
+}
+
+static inline int
+ia64_sn_set_os_feature(int feature)
+{
+ struct ia64_sal_retval rv;
+
+ SAL_CALL_NOLOCK(rv, SN_SAL_SET_OS_FEATURE_SET, feature, 0, 0, 0, 0, 0, 0);
+ return rv.status;
+}
+
#endif /* _ASM_IA64_SN_SN_SAL_H */
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index b2c79f0694f..cf4a950a0f4 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -76,6 +76,7 @@ struct thread_info {
#define TIF_SIGDELAYED 5 /* signal delayed from MCA/INIT/NMI/PMI context */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17
+#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
@@ -85,6 +86,7 @@ struct thread_info {
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SIGDELAYED (1 << TIF_SIGDELAYED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
/* "work to do on user-return" bits */
#define TIF_ALLWORK_MASK (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SIGDELAYED)
diff --git a/include/asm-ia64/unwind.h b/include/asm-ia64/unwind.h
index 61426ad3ecd..5df0276b049 100644
--- a/include/asm-ia64/unwind.h
+++ b/include/asm-ia64/unwind.h
@@ -114,13 +114,6 @@ extern void unw_remove_unwind_table (void *handle);
*/
extern void unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t);
-/*
- * Prepare to unwind from interruption. The pt-regs and switch-stack structures must have
- * be "adjacent" (no state modifications between pt-regs and switch-stack).
- */
-extern void unw_init_from_interruption (struct unw_frame_info *info, struct task_struct *t,
- struct pt_regs *pt, struct switch_stack *sw);
-
extern void unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t,
struct switch_stack *sw);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4b83cb23000..ed3bb19d133 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -904,6 +904,8 @@ extern int task_curr(const task_t *p);
extern int idle_cpu(int cpu);
extern int sched_setscheduler(struct task_struct *, int, struct sched_param *);
extern task_t *idle_task(int cpu);
+extern task_t *curr_task(int cpu);
+extern void set_curr_task(int cpu, task_t *p);
void yield(void);