WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ia64-devel

[Xen-ia64-devel] [PATCH 6/12][RFC]MCA handler support for Xen/ia64

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [PATCH 6/12][RFC]MCA handler support for Xen/ia64
From: SUZUKI Kazuhiro <kaz@xxxxxxxxxxxxxx>
Date: Wed, 06 Sep 2006 20:18:36 +0900 (JST)
Delivery-date: Wed, 06 Sep 2006 04:19:59 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20060906.201502.110833900.kaz@xxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20060906.201502.110833900.kaz@xxxxxxxxxxxxxxxxxx>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
[6/12]  Add sal emulation.[mca-fw_emul.patch]

Signed-off-by: Yutaka Ezaki <yutaka.ezaki@xxxxxxxxxxxxxx>
Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
Signed-off-by: SUZUKI Kazuhiro <kaz@xxxxxxxxxxxxxx>
diff -r 685bf9b75eb1 xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c       Mon Sep 04 14:48:03 2006 -0600
+++ b/xen/arch/ia64/xen/fw_emul.c       Wed Sep 06 14:06:30 2006 +0900
@@ -23,6 +23,7 @@
 #include <linux/efi.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
+#include <asm/xenmca.h>
 
 #include <public/sched.h>
 #include "hpsim_ssc.h"
@@ -32,6 +33,52 @@
 
 extern unsigned long running_on_sim;
 
+struct sal_mc_params {
+  u64 param_type;
+  u64 i_or_m;
+  u64 i_or_m_val;
+  u64 timeout;
+  u64 rz_always;
+} sal_mc_params[SAL_MC_PARAM_CPE_INT+1];
+
+struct sal_vectors {
+  u64 vector_type;
+  u64 handler_addr1;
+  u64 gp1;
+  u64 handler_len1;
+  u64 handler_addr2;
+  u64 gp2;
+  u64 handler_len2;
+} sal_vectors[SAL_VECTOR_OS_BOOT_RENDEZ+1];
+
+struct smp_call_args_t {
+       u64 type;
+       u64 ret;
+       void *data;
+}; 
+
+extern spinlock_t sal_queue_lock;
+
+#if defined(IA64_SAL_DEBUG_INFO)
+static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" };
+
+# define IA64_SAL_DEBUG(fmt...)        printk("sal_emulator: " fmt)
+#else
+# define IA64_SAL_DEBUG(fmt...)
+#endif
+
+void get_state_info_on(void *data) {
+       struct smp_call_args_t *arg = data;
+
+       arg->ret = ia64_sal_get_state_info(arg->type, (u64 *)arg->data);
+}
+
+void clear_state_info_on(void *data) {
+       struct smp_call_args_t *arg = data;
+
+       arg->ret = ia64_sal_clear_state_info(arg->type);
+}
+  
 struct sal_ret_values
 sal_emulator (long index, unsigned long in1, unsigned long in2,
              unsigned long in3, unsigned long in4, unsigned long in5,
@@ -102,27 +149,199 @@ sal_emulator (long index, unsigned long 
                        }
                }
                else
-                       printf("*** CALLED SAL_SET_VECTORS %lu.  IGNORED...\n",
-                              in1);
+               {
+                       if (in1 > sizeof(sal_vectors)/sizeof(sal_vectors[0])-1)
+                               BUG();
+                       sal_vectors[in1].vector_type    = in1;
+                       sal_vectors[in1].handler_addr1  = in2;
+                       sal_vectors[in1].gp1            = in3;
+                       sal_vectors[in1].handler_len1   = in4;
+                       sal_vectors[in1].handler_addr2  = in5;
+                       sal_vectors[in1].gp2            = in6;
+                       sal_vectors[in1].handler_len2   = in7;
+               }
                break;
            case SAL_GET_STATE_INFO:
-               /* No more info.  */
-               status = -5;
-               r9 = 0;
+               {
+                       sal_queue_entry_t *e;
+                       unsigned long flags;
+                       int size = ia64_sal_get_state_info_size(in1);
+                       static sal_log_record_header_t *record = NULL;
+
+                       if (record == NULL) {
+                               unsigned int pageorder;
+
+                               pageorder  = get_order_from_bytes(size);
+                               record = (sal_log_record_header_t 
*)alloc_xenheap_pages(pageorder);
+                       }
+                       memset(record, 0, size);
+
+                       spin_lock_irqsave(&sal_queue_lock, flags);
+                       if (list_empty(&sal_queue[in1])) {
+                               sal_log_record_header_t header;
+
+                               IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) "
+                                                                               
         "no sal_queue entry found.\n", rec_name[in1]);
+                               memset(&header, 0, sizeof(header));
+                               if (copy_to_user((void __user *)in3, &header, 
sizeof(header))) {
+                                       printk("sal_emulator: 
SAL_GET_STATE_INFO "
+                                                                "can't copy 
empty header to user: 0x%lx\n", in3);
+                               }
+                               status = -5;
+                               r9 = 0;
+                               spin_unlock_irqrestore(&sal_queue_lock, flags);
+                               break;
+                       }
+                       e = list_entry(sal_queue[in1].next, sal_queue_entry_t, 
list);
+
+                       spin_unlock_irqrestore(&sal_queue_lock, flags);
+
+                       if (e->cpuid == smp_processor_id()) {
+                               if (in1 == e->sal_info_type) {
+                                       IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) "
+                                                                               
                 "on current CPU.\n", rec_name[in1]);
+                               } else {
+                                       IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s 
<= %s) "
+                                                                               
                 "on current CPU.\n",
+                                                                               
                 rec_name[e->sal_info_type], 
+                                                                               
                 rec_name[in1]);
+                               }
+                               r9 = ia64_sal_get_state_info(e->sal_info_type, 
(u64 *)record);
+                               IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) "
+                                                                               
                 "returns %ld.\n", rec_name[in1], r9);
+                       } else {
+                               int ret;
+                               struct smp_call_args_t arg;
+
+                               if (in1 == e->sal_info_type) {
+                                       IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) "
+                                                                               
                 "on CPU#%d.\n", rec_name[in1], e->cpuid);
+                               } else {
+                                       IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s 
<= %s) "
+                                                                               
                 "on CPU#%d.\n", rec_name[e->sal_info_type],
+                                                                               
                 rec_name[in1], e->cpuid);
+                               }
+
+                               IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) "
+                                                                               
         "on CPU#%d.\n", rec_name[in1], e->cpuid);
+                               if (in1 != e->sal_info_type) {
+                                       IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) "
+                                                                               
                 "instead of %s.\n",
+                                                                               
                 rec_name[e->sal_info_type],
+                                                                               
                 rec_name[in1]);
+                               }
+                               arg.type = e->sal_info_type;
+                               arg.data = record;
+
+                               ret = smp_call_function_single(e->cpuid, 
get_state_info_on, &arg, 0, 1);
+                               r9 = arg.ret;
+                               IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) on 
CPU#%d "
+                                                                               
                 "returns %ld.\n", rec_name[in1], e->cpuid, r9);
+                               if (ret < 0) {
+                                       printk("sal_emulator: 
SAL_GET_STATE_INFO "
+                                                                
"smp_call_function_single error: %d\n", ret);
+                                       status = ret;
+                                       r9 = 0;
+                               }
+                       }
+                       if (in1 != e->sal_info_type && e->sal_info_type == 
SAL_INFO_TYPE_MCA) {
+                               record->severity = sal_log_severity_corrected;
+                               IA64_SAL_DEBUG("%s: 
IA64_SAL_CLEAR_STATE_INFO(SAL_INFO_TYPE_MCA) force\n",
+                                                                               
         __FUNCTION__);
+                       }
+
+                       if (copy_to_user((void __user *)in3, record, r9)) {
+                               printk("sal_emulator: SAL_GET_STATE_INFO "
+                                                        "can't copy to 
user!!!!\n");
+                               status = -5;
+                               r9 = 0;
+                       }
+               }
                break;
            case SAL_GET_STATE_INFO_SIZE:
-               /* Return a dummy size.  */
-               status = 0;
-               r9 = 128;
+               r9 = ia64_sal_get_state_info_size(in1);
                break;
            case SAL_CLEAR_STATE_INFO:
-               /* Noop.  */
+               {
+                       sal_queue_entry_t *e;
+                       unsigned long flags;
+
+                       spin_lock_irqsave(&sal_queue_lock, flags);
+                       if (list_empty(&sal_queue[in1])) {
+                               IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) "
+                                                                               
         "no sal_queue entry found.\n", rec_name[in1]);
+                               status = -5;
+                               r9 = 0;
+                               spin_unlock_irqrestore(&sal_queue_lock, flags);
+                               break;
+                       }
+                       e = list_entry(sal_queue[in1].next, 
sal_queue_entry_t,list);
+
+                       list_del(&e->list);
+                       spin_unlock_irqrestore(&sal_queue_lock, flags);
+
+                       if (e->cpuid == smp_processor_id()) {
+                               if (in1 == e->sal_info_type) {
+                                       
IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) "
+                                                                               
                 "on current CPU(%d).\n", rec_name[in1], e->cpuid);
+                               } else {
+                                       IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s 
<= %s) "
+                                                                               
                 "on current CPU(%d).\n",
+                                                                               
                 rec_name[e->sal_info_type], 
+                                                                               
                 rec_name[in1], e->cpuid);
+                               }
+                               r9 = 
ia64_sal_clear_state_info(e->sal_info_type);
+                               IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) "
+                                                                               
                 "returns %ld.\n", rec_name[in1], r9);
+                       } else {
+                               int ret;
+                               struct smp_call_args_t arg;
+
+                               if (in1 == e->sal_info_type) {
+                                       
IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) "
+                                                                               
                 "on CPU#%d.\n", rec_name[in1], e->cpuid);
+                               } else {
+                                       IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s 
<= %s) "
+                                                                               
                 "on CPU#%d.\n", rec_name[e->sal_info_type],
+                                                                               
                 rec_name[in1], e->cpuid);
+                               }
+
+                               IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) "
+                                                                               
         "on CPU#%d.\n", rec_name[in1], e->cpuid);
+                               if (in1 != e->sal_info_type) {
+                                       
IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) "
+                                                                               
                 "instead of %s.\n",
+                                                                               
                 rec_name[e->sal_info_type],
+                                                                               
                 rec_name[in1]);
+                               }
+
+                               arg.type = e->sal_info_type;
+
+                               ret = smp_call_function_single(e->cpuid, 
clear_state_info_on, &arg, 0, 1);
+                               r9 = arg.ret;
+                               IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) on 
CPU#%d "
+                                                                               
         "returns %ld.\n", rec_name[in1], e->cpuid, r9);
+                               if (ret < 0) {
+                                       printk("sal_emulator: 
SAL_CLEAR_STATE_INFO "
+                                                                
"smp_call_function_single error: %d\n", ret);
+                                       status = ret;
+                                       r9 = 0;
+                               }
+                       }
+                       xfree(e);
+               }
                break;
            case SAL_MC_RENDEZ:
                printf("*** CALLED SAL_MC_RENDEZ.  IGNORED...\n");
                break;
            case SAL_MC_SET_PARAMS:
-               printf("*** CALLED SAL_MC_SET_PARAMS.  IGNORED...\n");
+               if (in1 > sizeof(sal_mc_params)/sizeof(sal_mc_params[0]))
+                       BUG();
+               sal_mc_params[in1].param_type   = in1;
+               sal_mc_params[in1].i_or_m       = in2;
+               sal_mc_params[in1].i_or_m_val   = in3;
+               sal_mc_params[in1].timeout      = in4;
+               sal_mc_params[in1].rz_always    = in5;
                break;
            case SAL_CACHE_FLUSH:
                if (1) {
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel