[prev in list] [next in list] [prev in thread] [next in thread]
List: git-commits-head
Subject: ia64: Fix EFI runtime callbacks so they cannot corrupt fp regs. A few minor
From: Linux Kernel Mailing List <linux-kernel () vger ! kernel ! org>
Date: 2002-09-26 2:04:19
[Download RAW message or body]
ChangeSet 1.573.35.4, 2002/09/25 19:04:19-07:00, davidm@tiger.hpl.hp.com
ia64: Fix EFI runtime callbacks so they cannot corrupt fp regs. A few minor
other fixes.
# This patch includes the following deltas:
# ChangeSet 1.573.35.3 -> 1.573.35.4
# arch/ia64/kernel/efi.c 1.15 -> 1.16
# arch/ia64/mm/init.c 1.25 -> 1.26
# arch/ia64/kernel/iosapic.c 1.15 -> 1.16
# include/asm-ia64/iosapic.h 1.4 -> 1.5
#
arch/ia64/kernel/efi.c | 229 +++++++++++++++++++++++++++++++--------------
arch/ia64/kernel/iosapic.c | 30 ++++-
arch/ia64/mm/init.c | 2
include/asm-ia64/iosapic.h | 2
4 files changed, 185 insertions(+), 78 deletions(-)
diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
--- a/arch/ia64/kernel/efi.c Mon Oct 28 15:11:18 2002
+++ b/arch/ia64/kernel/efi.c Mon Oct 28 15:11:18 2002
@@ -60,66 +60,156 @@
static unsigned long mem_limit = ~0UL;
-static efi_status_t
-phys_get_time (efi_time_t *tm, efi_time_cap_t *tc)
-{
- return efi_call_phys(__va(runtime->get_time), __pa(tm), __pa(tc));
-}
-
-static efi_status_t
-phys_set_time (efi_time_t *tm)
-{
- return efi_call_phys(__va(runtime->set_time), __pa(tm));
-}
-
-static efi_status_t
-phys_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
- return efi_call_phys(__va(runtime->get_wakeup_time), __pa(enabled), __pa(pending),
- __pa(tm));
-}
-
-static efi_status_t
-phys_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
- return efi_call_phys(__va(runtime->set_wakeup_time), enabled, __pa(tm));
-}
-
-static efi_status_t
-phys_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
- unsigned long *data_size, void *data)
-{
- return efi_call_phys(__va(runtime->get_variable), __pa(name), __pa(vendor), __pa(attr),
- __pa(data_size), __pa(data));
-}
-
-static efi_status_t
-phys_get_next_variable (unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor)
-{
- return efi_call_phys(__va(runtime->get_next_variable), __pa(name_size), __pa(name),
- __pa(vendor));
-}
-
-static efi_status_t
-phys_set_variable (efi_char16_t *name, efi_guid_t *vendor, u32 attr,
- unsigned long data_size, void *data)
-{
- return efi_call_phys(__va(runtime->set_variable), __pa(name), __pa(vendor), attr,
- data_size, __pa(data));
-}
+#define efi_call_virt(f, args...) (*(f))(args)
-static efi_status_t
-phys_get_next_high_mono_count (u64 *count)
-{
- return efi_call_phys(__va(runtime->get_next_high_mono_count), __pa(count));
-}
-
-static void
-phys_reset_system (int reset_type, efi_status_t status,
- unsigned long data_size, efi_char16_t *data)
-{
- efi_call_phys(__va(runtime->reset_system), status, data_size, __pa(data));
-}
+#define STUB_GET_TIME(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), adjust_arg(tm), \
+ adjust_arg(tc)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_SET_TIME(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_set_time (efi_time_t *tm) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), adjust_arg(tm)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_GET_WAKEUP_TIME(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_get_wakeup_time_t *) __va(runtime->get_wakeup_time), \
+ adjust_arg(enabled), adjust_arg(pending), adjust_arg(tm)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_SET_WAKEUP_TIME(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time), \
+ enabled, adjust_arg(tm)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_GET_VARIABLE(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr, \
+ unsigned long *data_size, void *data) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_get_variable_t *) __va(runtime->get_variable), \
+ adjust_arg(name), adjust_arg(vendor), adjust_arg(attr), \
+ adjust_arg(data_size), adjust_arg(data)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_GET_NEXT_VARIABLE(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_get_next_variable_t *) __va(runtime->get_next_variable), \
+ adjust_arg(name_size), adjust_arg(name), adjust_arg(vendor)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_SET_VARIABLE(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, u32 attr, \
+ unsigned long data_size, void *data) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_set_variable_t *) __va(runtime->set_variable), \
+ adjust_arg(name), adjust_arg(vendor), attr, data_size, \
+ adjust_arg(data)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_GET_NEXT_HIGH_MONO_COUNT(prefix, adjust_arg) \
+static efi_status_t \
+prefix##_get_next_high_mono_count (u64 *count) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ efi_status_t ret; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ ret = efi_call_##prefix((efi_get_next_high_mono_count_t *) \
+ __va(runtime->get_next_high_mono_count), adjust_arg(count)); \
+ ia64_load_scratch_fpregs(fr); \
+ return ret; \
+}
+
+#define STUB_RESET_SYSTEM(prefix, adjust_arg) \
+static void \
+prefix##_reset_system (int reset_type, efi_status_t status, \
+ unsigned long data_size, efi_char16_t *data) \
+{ \
+ struct ia64_fpreg fr[6]; \
+ \
+ ia64_save_scratch_fpregs(fr); \
+ efi_call_##prefix((efi_reset_system_t *) __va(runtime->reset_system), \
+ reset_type, status, data_size, adjust_arg(data)); \
+ /* should not return, but just in case... */ \
+ ia64_load_scratch_fpregs(fr); \
+}
+
+STUB_GET_TIME(phys, __pa)
+STUB_SET_TIME(phys, __pa)
+STUB_GET_WAKEUP_TIME(phys, __pa)
+STUB_SET_WAKEUP_TIME(phys, __pa)
+STUB_GET_VARIABLE(phys, __pa)
+STUB_GET_NEXT_VARIABLE(phys, __pa)
+STUB_SET_VARIABLE(phys, __pa)
+STUB_GET_NEXT_HIGH_MONO_COUNT(phys, __pa)
+STUB_RESET_SYSTEM(phys, __pa)
+
+STUB_GET_TIME(virt, )
+STUB_SET_TIME(virt, )
+STUB_GET_WAKEUP_TIME(virt, )
+STUB_SET_WAKEUP_TIME(virt, )
+STUB_GET_VARIABLE(virt, )
+STUB_GET_NEXT_VARIABLE(virt, )
+STUB_SET_VARIABLE(virt, )
+STUB_GET_NEXT_HIGH_MONO_COUNT(virt, )
+STUB_RESET_SYSTEM(virt, )
void
efi_gettimeofday (struct timeval *tv)
@@ -574,18 +664,17 @@
}
/*
- * Now that EFI is in virtual mode, we arrange for EFI functions to be
- * called directly:
+ * Now that EFI is in virtual mode, we call the EFI functions more efficiently:
*/
- efi.get_time = __va(runtime->get_time);
- efi.set_time = __va(runtime->set_time);
- efi.get_wakeup_time = __va(runtime->get_wakeup_time);
- efi.set_wakeup_time = __va(runtime->set_wakeup_time);
- efi.get_variable = __va(runtime->get_variable);
- efi.get_next_variable = __va(runtime->get_next_variable);
- efi.set_variable = __va(runtime->set_variable);
- efi.get_next_high_mono_count = __va(runtime->get_next_high_mono_count);
- efi.reset_system = __va(runtime->reset_system);
+ efi.get_time = virt_get_time;
+ efi.set_time = virt_set_time;
+ efi.get_wakeup_time = virt_get_wakeup_time;
+ efi.set_wakeup_time = virt_set_wakeup_time;
+ efi.get_variable = virt_get_variable;
+ efi.get_next_variable = virt_get_next_variable;
+ efi.set_variable = virt_set_variable;
+ efi.get_next_high_mono_count = virt_get_next_high_mono_count;
+ efi.reset_system = virt_reset_system;
}
/*
diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
--- a/arch/ia64/kernel/iosapic.c Mon Oct 28 15:11:18 2002
+++ b/arch/ia64/kernel/iosapic.c Mon Oct 28 15:11:18 2002
@@ -133,12 +133,8 @@
return -1;
}
-/*
- * Translate GSI number to the corresponding IA-64 interrupt vector. If no
- * entry exists, return -1.
- */
-int
-gsi_to_vector (unsigned int gsi)
+static inline int
+_gsi_to_vector (unsigned int gsi)
{
struct iosapic_intr_info *info;
@@ -148,6 +144,26 @@
return -1;
}
+/*
+ * Translate GSI number to the corresponding IA-64 interrupt vector. If no
+ * entry exists, return -1.
+ */
+inline int
+gsi_to_vector (unsigned int gsi)
+{
+ return _gsi_to_vector(gsi);
+}
+
+int
+gsi_to_irq (unsigned int gsi)
+{
+ /*
+ * XXX fix me: this assumes an identity mapping vetween IA-64 vector and Linux irq
+ * numbers...
+ */
+ return _gsi_to_vector(gsi);
+}
+
static void
set_rte (unsigned int vector, unsigned int dest)
{
@@ -157,7 +173,7 @@
int rte_index;
char redir;
- DBG(KERN_DEBUG"IOSAPIC: routing vector %d to %x\n", vector, dest);
+ DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
rte_index = iosapic_intr_info[vector].rte_index;
if (rte_index < 0)
diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
--- a/arch/ia64/mm/init.c Mon Oct 28 15:11:18 2002
+++ b/arch/ia64/mm/init.c Mon Oct 28 15:11:18 2002
@@ -78,7 +78,7 @@
vma->vm_mm = current->mm;
vma->vm_start = IA64_RBS_BOT;
vma->vm_end = vma->vm_start + PAGE_SIZE;
- vma->vm_page_prot = protection_map[VM_READ | VM_WRITE];
+ vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE|VM_GROWSUP;
vma->vm_ops = NULL;
vma->vm_pgoff = 0;
diff -Nru a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
--- a/include/asm-ia64/iosapic.h Mon Oct 28 15:11:18 2002
+++ b/include/asm-ia64/iosapic.h Mon Oct 28 15:11:18 2002
@@ -55,6 +55,8 @@
unsigned int gsi_base,
int pcat_compat);
extern int gsi_to_vector (unsigned int gsi);
+extern int gsi_to_irq (unsigned int gsi);
+extern void iosapic_parse_prt (void);
extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
unsigned long edge_triggered,
u32 gsi_base, char *iosapic_address);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic