@@ -103,3 +103,94 @@ static int kvm_handle_csr(struct kvm_vcpu *vcpu, larch_inst inst)
103
103
104
104
return EMULATE_DONE ;
105
105
}
106
+
107
+ int kvm_emu_iocsr (larch_inst inst , struct kvm_run * run , struct kvm_vcpu * vcpu )
108
+ {
109
+ int ret ;
110
+ unsigned long val ;
111
+ u32 addr , rd , rj , opcode ;
112
+
113
+ /*
114
+ * Each IOCSR with different opcode
115
+ */
116
+ rd = inst .reg2_format .rd ;
117
+ rj = inst .reg2_format .rj ;
118
+ opcode = inst .reg2_format .opcode ;
119
+ addr = vcpu -> arch .gprs [rj ];
120
+ ret = EMULATE_DO_IOCSR ;
121
+ run -> iocsr_io .phys_addr = addr ;
122
+ run -> iocsr_io .is_write = 0 ;
123
+
124
+ /* LoongArch is Little endian */
125
+ switch (opcode ) {
126
+ case iocsrrdb_op :
127
+ run -> iocsr_io .len = 1 ;
128
+ break ;
129
+ case iocsrrdh_op :
130
+ run -> iocsr_io .len = 2 ;
131
+ break ;
132
+ case iocsrrdw_op :
133
+ run -> iocsr_io .len = 4 ;
134
+ break ;
135
+ case iocsrrdd_op :
136
+ run -> iocsr_io .len = 8 ;
137
+ break ;
138
+ case iocsrwrb_op :
139
+ run -> iocsr_io .len = 1 ;
140
+ run -> iocsr_io .is_write = 1 ;
141
+ break ;
142
+ case iocsrwrh_op :
143
+ run -> iocsr_io .len = 2 ;
144
+ run -> iocsr_io .is_write = 1 ;
145
+ break ;
146
+ case iocsrwrw_op :
147
+ run -> iocsr_io .len = 4 ;
148
+ run -> iocsr_io .is_write = 1 ;
149
+ break ;
150
+ case iocsrwrd_op :
151
+ run -> iocsr_io .len = 8 ;
152
+ run -> iocsr_io .is_write = 1 ;
153
+ break ;
154
+ default :
155
+ ret = EMULATE_FAIL ;
156
+ break ;
157
+ }
158
+
159
+ if (ret == EMULATE_DO_IOCSR ) {
160
+ if (run -> iocsr_io .is_write ) {
161
+ val = vcpu -> arch .gprs [rd ];
162
+ memcpy (run -> iocsr_io .data , & val , run -> iocsr_io .len );
163
+ }
164
+ vcpu -> arch .io_gpr = rd ;
165
+ }
166
+
167
+ return ret ;
168
+ }
169
+
170
+ int kvm_complete_iocsr_read (struct kvm_vcpu * vcpu , struct kvm_run * run )
171
+ {
172
+ enum emulation_result er = EMULATE_DONE ;
173
+ unsigned long * gpr = & vcpu -> arch .gprs [vcpu -> arch .io_gpr ];
174
+
175
+ switch (run -> iocsr_io .len ) {
176
+ case 1 :
177
+ * gpr = * (s8 * )run -> iocsr_io .data ;
178
+ break ;
179
+ case 2 :
180
+ * gpr = * (s16 * )run -> iocsr_io .data ;
181
+ break ;
182
+ case 4 :
183
+ * gpr = * (s32 * )run -> iocsr_io .data ;
184
+ break ;
185
+ case 8 :
186
+ * gpr = * (s64 * )run -> iocsr_io .data ;
187
+ break ;
188
+ default :
189
+ kvm_err ("Bad IOCSR length: %d, addr is 0x%lx\n" ,
190
+ run -> iocsr_io .len , vcpu -> arch .badv );
191
+ er = EMULATE_FAIL ;
192
+ break ;
193
+ }
194
+
195
+ return er ;
196
+ }
0 commit comments