summaryrefslogtreecommitdiffstats
path: root/include/asm-ia64/mca.h
diff options
context:
space:
mode:
authorKeith Owens <kaos@sgi.com>2005-09-11 17:22:53 +1000
committerTony Luck <tony.luck@intel.com>2005-09-11 14:08:41 -0700
commit7f613c7d2203ae137d98fc1c38abc30fd7048637 (patch)
treed8155a5cca33e4fe178625396886fcbb81f39e7a /include/asm-ia64/mca.h
parent289d773ee89ea80dcc364ef97d1be7ad1817387e (diff)
downloadtalos-op-linux-7f613c7d2203ae137d98fc1c38abc30fd7048637.tar.gz
talos-op-linux-7f613c7d2203ae137d98fc1c38abc30fd7048637.zip
[PATCH] MCA/INIT: use per cpu stacks
The bulk of the change. Use per cpu MCA/INIT stacks. Change the SAL to OS state (sos) to be per process. Do all the assembler work on the MCA/INIT stacks, leaving the original stack alone. Pass per cpu state data to the C handlers for MCA and INIT, which also means changing the mca_drv interfaces slightly. Lots of verification on whether the original stack is usable before converting it to a sleeping process. Signed-off-by: Keith Owens <kaos@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'include/asm-ia64/mca.h')
-rw-r--r--include/asm-ia64/mca.h102
1 files changed, 64 insertions, 38 deletions
diff --git a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h
index 149ad0118455..97a28b8b2ddd 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 */
OpenPOWER on IntegriCloud