debuggers.hg
changeset 12860:7452d58e4a3b
[IA64] MCA support - Add sal emulation
Signed-off-by: Yutaka Ezaki <yutaka.ezaki@jp.fujitsu.com>
Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Kazuhiro Suzuki <kaz@jp.fujitsu.com>
Signed-off-by: Yutaka Ezaki <yutaka.ezaki@jp.fujitsu.com>
Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Kazuhiro Suzuki <kaz@jp.fujitsu.com>
author | awilliam@xenbuild.aw |
---|---|
date | Sun Oct 29 09:27:16 2006 -0700 (2006-10-29) |
parents | 6384ff711405 |
children | 5dd8306e9032 |
files | xen/arch/ia64/xen/fw_emul.c |
line diff
1.1 --- a/xen/arch/ia64/xen/fw_emul.c Sun Oct 29 09:27:15 2006 -0700 1.2 +++ b/xen/arch/ia64/xen/fw_emul.c Sun Oct 29 09:27:16 2006 -0700 1.3 @@ -22,6 +22,7 @@ 1.4 #include <linux/efi.h> 1.5 #include <asm/pal.h> 1.6 #include <asm/sal.h> 1.7 +#include <asm/xenmca.h> 1.8 1.9 #include <public/sched.h> 1.10 #include "hpsim_ssc.h" 1.11 @@ -34,6 +35,93 @@ 1.12 1.13 extern unsigned long running_on_sim; 1.14 1.15 +struct sal_mc_params { 1.16 + u64 param_type; 1.17 + u64 i_or_m; 1.18 + u64 i_or_m_val; 1.19 + u64 timeout; 1.20 + u64 rz_always; 1.21 +} sal_mc_params[SAL_MC_PARAM_CPE_INT + 1]; 1.22 + 1.23 +struct sal_vectors { 1.24 + u64 vector_type; 1.25 + u64 handler_addr1; 1.26 + u64 gp1; 1.27 + u64 handler_len1; 1.28 + u64 handler_addr2; 1.29 + u64 gp2; 1.30 + u64 handler_len2; 1.31 +} sal_vectors[SAL_VECTOR_OS_BOOT_RENDEZ + 1]; 1.32 + 1.33 +struct smp_call_args_t { 1.34 + u64 type; 1.35 + u64 ret; 1.36 + u64 target; 1.37 + struct domain *domain; 1.38 + int corrected; 1.39 + int status; 1.40 + void *data; 1.41 +}; 1.42 + 1.43 +extern sal_log_record_header_t *sal_record; 1.44 +DEFINE_SPINLOCK(sal_record_lock); 1.45 + 1.46 +extern spinlock_t sal_queue_lock; 1.47 + 1.48 +#define IA64_SAL_NO_INFORMATION_AVAILABLE -5 1.49 + 1.50 +#if defined(IA64_SAL_DEBUG_INFO) 1.51 +static const char * const rec_name[] = { "MCA", "INIT", "CMC", "CPE" }; 1.52 + 1.53 +# define IA64_SAL_DEBUG(fmt...) printk("sal_emulator: " fmt) 1.54 +#else 1.55 +# define IA64_SAL_DEBUG(fmt...) 1.56 +#endif 1.57 + 1.58 +void get_state_info_on(void *data) { 1.59 + struct smp_call_args_t *arg = data; 1.60 + int flags; 1.61 + 1.62 + spin_lock_irqsave(&sal_record_lock, flags); 1.63 + memset(sal_record, 0, ia64_sal_get_state_info_size(arg->type)); 1.64 + arg->ret = ia64_sal_get_state_info(arg->type, (u64 *)sal_record); 1.65 + IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) on CPU#%d returns %ld.\n", 1.66 + rec_name[arg->type], smp_processor_id(), arg->ret); 1.67 + if (arg->corrected) { 1.68 + sal_record->severity = sal_log_severity_corrected; 1.69 + IA64_SAL_DEBUG("%s: IA64_SAL_CLEAR_STATE_INFO(SAL_INFO_TYPE_MCA)" 1.70 + " force\n", __FUNCTION__); 1.71 + } 1.72 + if (arg->ret > 0) { 1.73 + /* 1.74 + * Save current->domain and set to local(caller) domain for 1.75 + * xencomm_paddr_to_maddr() which calculates maddr from 1.76 + * paddr using mpa value of current->domain. 1.77 + */ 1.78 + struct domain *save; 1.79 + save = current->domain; 1.80 + current->domain = arg->domain; 1.81 + if (xencomm_copy_to_guest((void*)arg->target, 1.82 + sal_record, arg->ret, 0)) { 1.83 + printk("SAL_GET_STATE_INFO can't copy to user!!!!\n"); 1.84 + arg->status = IA64_SAL_NO_INFORMATION_AVAILABLE; 1.85 + arg->ret = 0; 1.86 + } 1.87 + /* Restore current->domain to saved value. */ 1.88 + current->domain = save; 1.89 + } 1.90 + spin_unlock_irqrestore(&sal_record_lock, flags); 1.91 +} 1.92 + 1.93 +void clear_state_info_on(void *data) { 1.94 + struct smp_call_args_t *arg = data; 1.95 + 1.96 + arg->ret = ia64_sal_clear_state_info(arg->type); 1.97 + IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) on CPU#%d returns %ld.\n", 1.98 + rec_name[arg->type], smp_processor_id(), arg->ret); 1.99 + 1.100 +} 1.101 + 1.102 struct sal_ret_values 1.103 sal_emulator (long index, unsigned long in1, unsigned long in2, 1.104 unsigned long in3, unsigned long in4, unsigned long in5, 1.105 @@ -104,27 +192,157 @@ sal_emulator (long index, unsigned long 1.106 } 1.107 } 1.108 else 1.109 - printk("*** CALLED SAL_SET_VECTORS %lu. IGNORED...\n", 1.110 - in1); 1.111 + { 1.112 + if (in1 > sizeof(sal_vectors)/sizeof(sal_vectors[0])-1) 1.113 + BUG(); 1.114 + sal_vectors[in1].vector_type = in1; 1.115 + sal_vectors[in1].handler_addr1 = in2; 1.116 + sal_vectors[in1].gp1 = in3; 1.117 + sal_vectors[in1].handler_len1 = in4; 1.118 + sal_vectors[in1].handler_addr2 = in5; 1.119 + sal_vectors[in1].gp2 = in6; 1.120 + sal_vectors[in1].handler_len2 = in7; 1.121 + } 1.122 break; 1.123 case SAL_GET_STATE_INFO: 1.124 - /* No more info. */ 1.125 - status = -5; 1.126 - r9 = 0; 1.127 + { 1.128 + sal_queue_entry_t *e; 1.129 + unsigned long flags; 1.130 + struct smp_call_args_t arg; 1.131 + 1.132 + spin_lock_irqsave(&sal_queue_lock, flags); 1.133 + if (list_empty(&sal_queue[in1])) { 1.134 + sal_log_record_header_t header; 1.135 + XEN_GUEST_HANDLE(void) handle = 1.136 + *(XEN_GUEST_HANDLE(void)*)&in3; 1.137 + 1.138 + IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s) " 1.139 + "no sal_queue entry found.\n", 1.140 + rec_name[in1]); 1.141 + memset(&header, 0, sizeof(header)); 1.142 + 1.143 + if (copy_to_guest(handle, &header, 1)) { 1.144 + printk("sal_emulator: " 1.145 + "SAL_GET_STATE_INFO can't copy " 1.146 + "empty header to user: 0x%lx\n", 1.147 + in3); 1.148 + } 1.149 + status = IA64_SAL_NO_INFORMATION_AVAILABLE; 1.150 + r9 = 0; 1.151 + spin_unlock_irqrestore(&sal_queue_lock, flags); 1.152 + break; 1.153 + } 1.154 + e = list_entry(sal_queue[in1].next, 1.155 + sal_queue_entry_t, list); 1.156 + spin_unlock_irqrestore(&sal_queue_lock, flags); 1.157 + 1.158 + IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s <= %s) " 1.159 + "on CPU#%d.\n", 1.160 + rec_name[e->sal_info_type], 1.161 + rec_name[in1], e->cpuid); 1.162 + 1.163 + arg.type = e->sal_info_type; 1.164 + arg.target = in3; 1.165 + arg.corrected = !!((in1 != e->sal_info_type) && 1.166 + (e->sal_info_type == SAL_INFO_TYPE_MCA)); 1.167 + arg.domain = current->domain; 1.168 + arg.status = 0; 1.169 + 1.170 + if (e->cpuid == smp_processor_id()) { 1.171 + IA64_SAL_DEBUG("SAL_GET_STATE_INFO: local\n"); 1.172 + get_state_info_on(&arg); 1.173 + } else { 1.174 + int ret; 1.175 + IA64_SAL_DEBUG("SAL_GET_STATE_INFO: remote\n"); 1.176 + ret = smp_call_function_single(e->cpuid, 1.177 + get_state_info_on, 1.178 + &arg, 0, 1); 1.179 + if (ret < 0) { 1.180 + printk("SAL_GET_STATE_INFO " 1.181 + "smp_call_function_single error:" 1.182 + " %d\n", ret); 1.183 + arg.ret = 0; 1.184 + arg.status = 1.185 + IA64_SAL_NO_INFORMATION_AVAILABLE; 1.186 + } 1.187 + } 1.188 + r9 = arg.ret; 1.189 + status = arg.status; 1.190 + if (r9 == 0) { 1.191 + spin_lock_irqsave(&sal_queue_lock, flags); 1.192 + list_del(&e->list); 1.193 + spin_unlock_irqrestore(&sal_queue_lock, flags); 1.194 + xfree(e); 1.195 + } 1.196 + } 1.197 break; 1.198 case SAL_GET_STATE_INFO_SIZE: 1.199 - /* Return a dummy size. */ 1.200 - status = 0; 1.201 - r9 = 128; 1.202 + r9 = ia64_sal_get_state_info_size(in1); 1.203 break; 1.204 case SAL_CLEAR_STATE_INFO: 1.205 - /* Noop. */ 1.206 + { 1.207 + sal_queue_entry_t *e; 1.208 + unsigned long flags; 1.209 + struct smp_call_args_t arg; 1.210 + 1.211 + spin_lock_irqsave(&sal_queue_lock, flags); 1.212 + if (list_empty(&sal_queue[in1])) { 1.213 + IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s) " 1.214 + "no sal_queue entry found.\n", 1.215 + rec_name[in1]); 1.216 + status = IA64_SAL_NO_INFORMATION_AVAILABLE; 1.217 + r9 = 0; 1.218 + spin_unlock_irqrestore(&sal_queue_lock, flags); 1.219 + break; 1.220 + } 1.221 + e = list_entry(sal_queue[in1].next, 1.222 + sal_queue_entry_t, list); 1.223 + 1.224 + list_del(&e->list); 1.225 + spin_unlock_irqrestore(&sal_queue_lock, flags); 1.226 + 1.227 + IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO(%s <= %s) " 1.228 + "on CPU#%d.\n", 1.229 + rec_name[e->sal_info_type], 1.230 + rec_name[in1], e->cpuid); 1.231 + 1.232 + 1.233 + arg.type = e->sal_info_type; 1.234 + arg.status = 0; 1.235 + if (e->cpuid == smp_processor_id()) { 1.236 + IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: local\n"); 1.237 + clear_state_info_on(&arg); 1.238 + } else { 1.239 + int ret; 1.240 + IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: remote\n"); 1.241 + ret = smp_call_function_single(e->cpuid, 1.242 + clear_state_info_on, &arg, 0, 1); 1.243 + if (ret < 0) { 1.244 + printk("sal_emulator: " 1.245 + "SAL_CLEAR_STATE_INFO " 1.246 + "smp_call_function_single error:" 1.247 + " %d\n", ret); 1.248 + arg.ret = 0; 1.249 + arg.status = 1.250 + IA64_SAL_NO_INFORMATION_AVAILABLE; 1.251 + } 1.252 + } 1.253 + r9 = arg.ret; 1.254 + status = arg.status; 1.255 + xfree(e); 1.256 + } 1.257 break; 1.258 case SAL_MC_RENDEZ: 1.259 printk("*** CALLED SAL_MC_RENDEZ. IGNORED...\n"); 1.260 break; 1.261 case SAL_MC_SET_PARAMS: 1.262 - printk("*** CALLED SAL_MC_SET_PARAMS. IGNORED...\n"); 1.263 + if (in1 > sizeof(sal_mc_params)/sizeof(sal_mc_params[0])) 1.264 + BUG(); 1.265 + sal_mc_params[in1].param_type = in1; 1.266 + sal_mc_params[in1].i_or_m = in2; 1.267 + sal_mc_params[in1].i_or_m_val = in3; 1.268 + sal_mc_params[in1].timeout = in4; 1.269 + sal_mc_params[in1].rz_always = in5; 1.270 break; 1.271 case SAL_CACHE_FLUSH: 1.272 if (1) {