]> git.sur5r.net Git - openocd/blob - src/target/armv8.c
aarch64: introduce dpm extension for ARMv8
[openocd] / src / target / armv8.c
1 /***************************************************************************
2  *   Copyright (C) 2015 by David Ung                                       *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <helper/replacements.h>
24
25 #include "armv8.h"
26 #include "arm_disassembler.h"
27
28 #include "register.h"
29 #include <helper/binarybuffer.h>
30 #include <helper/command.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include "armv8_opcodes.h"
37 #include "arm_opcodes.h"
38 #include "target.h"
39 #include "target_type.h"
40
41 static const char * const armv8_state_strings[] = {
42         "ARM", "Thumb", "Jazelle", "ThumbEE", "ARM64",
43 };
44
45 static const struct {
46         const char *name;
47         unsigned psr;
48         /* For user and system modes, these list indices for all registers.
49          * otherwise they're just indices for the shadow registers and SPSR.
50          */
51         unsigned short n_indices;
52         const uint8_t *indices;
53 } armv8_mode_data[] = {
54         /* These special modes are currently only supported
55          * by ARMv6M and ARMv7M profiles */
56         {
57                 .name = "EL0T",
58                 .psr = ARMV8_64_EL0T,
59         },
60         {
61                 .name = "EL1T",
62                 .psr = ARMV8_64_EL1T,
63         },
64         {
65                 .name = "EL1H",
66                 .psr = ARMV8_64_EL1H,
67         },
68         {
69                 .name = "EL2T",
70                 .psr = ARMV8_64_EL2T,
71         },
72         {
73                 .name = "EL2H",
74                 .psr = ARMV8_64_EL2H,
75         },
76         {
77                 .name = "EL3T",
78                 .psr = ARMV8_64_EL3T,
79         },
80         {
81                 .name = "EL3H",
82                 .psr = ARMV8_64_EL3H,
83         },
84 };
85
86 /** Map PSR mode bits to the name of an ARM processor operating mode. */
87 const char *armv8_mode_name(unsigned psr_mode)
88 {
89         for (unsigned i = 0; i < ARRAY_SIZE(armv8_mode_data); i++) {
90                 if (armv8_mode_data[i].psr == psr_mode)
91                         return armv8_mode_data[i].name;
92         }
93         LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
94         return "UNRECOGNIZED";
95 }
96
97 int armv8_mode_to_number(enum arm_mode mode)
98 {
99         switch (mode) {
100                 case ARM_MODE_ANY:
101                 /* map MODE_ANY to user mode */
102                 case ARM_MODE_USR:
103                         return 0;
104                 case ARM_MODE_FIQ:
105                         return 1;
106                 case ARM_MODE_IRQ:
107                         return 2;
108                 case ARM_MODE_SVC:
109                         return 3;
110                 case ARM_MODE_ABT:
111                         return 4;
112                 case ARM_MODE_UND:
113                         return 5;
114                 case ARM_MODE_SYS:
115                         return 6;
116                 case ARM_MODE_MON:
117                         return 7;
118                 case ARMV8_64_EL0T:
119                         return 8;
120                 case ARMV8_64_EL1T:
121                         return 9;
122                 case ARMV8_64_EL1H:
123                         return 10;
124                 case ARMV8_64_EL2T:
125                         return 11;
126                 case ARMV8_64_EL2H:
127                         return 12;
128                 case ARMV8_64_EL3T:
129                         return 13;
130                 case ARMV8_64_EL3H:
131                         return 14;
132
133                 default:
134                         LOG_ERROR("invalid mode value encountered %d", mode);
135                         return -1;
136         }
137 }
138
139
140 static int armv8_read_core_reg(struct target *target, struct reg *r,
141         int num, enum arm_mode mode)
142 {
143         uint64_t reg_value;
144         int retval;
145         struct arm_reg *armv8_core_reg;
146         struct armv8_common *armv8 = target_to_armv8(target);
147
148         assert(num < (int)armv8->arm.core_cache->num_regs);
149
150         armv8_core_reg = armv8->arm.core_cache->reg_list[num].arch_info;
151         retval = armv8->load_core_reg_u64(target,
152                         armv8_core_reg->num, &reg_value);
153
154         buf_set_u64(armv8->arm.core_cache->reg_list[num].value, 0, 64, reg_value);
155         armv8->arm.core_cache->reg_list[num].valid = 1;
156         armv8->arm.core_cache->reg_list[num].dirty = 0;
157
158         return retval;
159 }
160
161 #if 0
162 static int armv8_write_core_reg(struct target *target, struct reg *r,
163         int num, enum arm_mode mode, target_addr_t value)
164 {
165         int retval;
166         struct arm_reg *armv8_core_reg;
167         struct armv8_common *armv8 = target_to_armv8(target);
168
169         assert(num < (int)armv8->arm.core_cache->num_regs);
170
171         armv8_core_reg = armv8->arm.core_cache->reg_list[num].arch_info;
172         retval = armv8->store_core_reg_u64(target,
173                                             armv8_core_reg->num,
174                                             value);
175         if (retval != ERROR_OK) {
176                 LOG_ERROR("JTAG failure");
177                 armv8->arm.core_cache->reg_list[num].dirty = armv8->arm.core_cache->reg_list[num].valid;
178                 return ERROR_JTAG_DEVICE_ERROR;
179         }
180
181         LOG_DEBUG("write core reg %i value 0x%" PRIx64 "", num, value);
182         armv8->arm.core_cache->reg_list[num].valid = 1;
183         armv8->arm.core_cache->reg_list[num].dirty = 0;
184
185         return ERROR_OK;
186 }
187 #endif
188 /**
189  * Configures host-side ARM records to reflect the specified CPSR.
190  * Later, code can use arm_reg_current() to map register numbers
191  * according to how they are exposed by this mode.
192  */
193 void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
194 {
195         uint32_t mode = cpsr & 0x1F;
196
197         /* NOTE:  this may be called very early, before the register
198          * cache is set up.  We can't defend against many errors, in
199          * particular against CPSRs that aren't valid *here* ...
200          */
201         if (arm->cpsr) {
202                 buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
203                 arm->cpsr->valid = 1;
204                 arm->cpsr->dirty = 0;
205         }
206
207         /* Older ARMs won't have the J bit */
208         enum arm_state state = 0xFF;
209
210         if (((cpsr & 0x10) >> 4) == 0) {
211                 state = ARM_STATE_AARCH64;
212         } else {
213                 if (cpsr & (1 << 5)) {  /* T */
214                         if (cpsr & (1 << 24)) { /* J */
215                                 LOG_WARNING("ThumbEE -- incomplete support");
216                                 state = ARM_STATE_THUMB_EE;
217                         } else
218                                 state = ARM_STATE_THUMB;
219                 } else {
220                         if (cpsr & (1 << 24)) { /* J */
221                                 LOG_ERROR("Jazelle state handling is BROKEN!");
222                                 state = ARM_STATE_JAZELLE;
223                         } else
224                                 state = ARM_STATE_ARM;
225                 }
226         }
227         arm->core_state = state;
228         if (arm->core_state == ARM_STATE_AARCH64) {
229                 switch (mode) {
230                         case SYSTEM_AAR64_MODE_EL0t:
231                                 arm->core_mode = ARMV8_64_EL0T;
232                         break;
233                         case SYSTEM_AAR64_MODE_EL1t:
234                                 arm->core_mode = ARMV8_64_EL0T;
235                         break;
236                         case SYSTEM_AAR64_MODE_EL1h:
237                                 arm->core_mode = ARMV8_64_EL1H;
238                         break;
239                         case SYSTEM_AAR64_MODE_EL2t:
240                                 arm->core_mode = ARMV8_64_EL2T;
241                         break;
242                         case SYSTEM_AAR64_MODE_EL2h:
243                                 arm->core_mode = ARMV8_64_EL2H;
244                         break;
245                         case SYSTEM_AAR64_MODE_EL3t:
246                                 arm->core_mode = ARMV8_64_EL3T;
247                         break;
248                         case SYSTEM_AAR64_MODE_EL3h:
249                                 arm->core_mode = ARMV8_64_EL3H;
250                         break;
251                         default:
252                                 LOG_DEBUG("unknow mode 0x%x", (unsigned) (mode));
253                         break;
254                 }
255         } else {
256                 arm->core_mode = mode;
257         }
258
259         LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
260                 armv8_mode_name(arm->core_mode),
261                 armv8_state_strings[arm->core_state]);
262 }
263
264 static void armv8_show_fault_registers(struct target *target)
265 {
266         /* TODO */
267 }
268
269 static int armv8_read_ttbcr(struct target *target)
270 {
271         struct armv8_common *armv8 = target_to_armv8(target);
272         struct arm_dpm *dpm = armv8->arm.dpm;
273         uint32_t ttbcr;
274         int retval = dpm->prepare(dpm);
275         if (retval != ERROR_OK)
276                 goto done;
277         /*  MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
278         retval = dpm->instr_read_data_r0(dpm,
279                         ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
280                         &ttbcr);
281         if (retval != ERROR_OK)
282                 goto done;
283         armv8->armv8_mmu.ttbr1_used = ((ttbcr & 0x7) != 0) ? 1 : 0;
284         armv8->armv8_mmu.ttbr0_mask  = 7 << (32 - ((ttbcr & 0x7)));
285 #if 0
286         LOG_INFO("ttb1 %s ,ttb0_mask %x",
287                 armv8->armv8_mmu.ttbr1_used ? "used" : "not used",
288                 armv8->armv8_mmu.ttbr0_mask);
289 #endif
290         if (armv8->armv8_mmu.ttbr1_used == 1) {
291                 LOG_INFO("SVC access above %" PRIx32,
292                          (uint32_t)(0xffffffff & armv8->armv8_mmu.ttbr0_mask));
293                 armv8->armv8_mmu.os_border = 0xffffffff & armv8->armv8_mmu.ttbr0_mask;
294         } else {
295                 /*  fix me , default is hard coded LINUX border  */
296                 armv8->armv8_mmu.os_border = 0xc0000000;
297         }
298 done:
299         dpm->finish(dpm);
300         return retval;
301 }
302
303
304 /*  method adapted to cortex A : reused arm v4 v5 method*/
305 int armv8_mmu_translate_va(struct target *target,  uint32_t va, uint32_t *val)
306 {
307         uint32_t first_lvl_descriptor = 0x0;
308         uint32_t second_lvl_descriptor = 0x0;
309         int retval;
310         struct armv8_common *armv8 = target_to_armv8(target);
311         struct arm_dpm *dpm = armv8->arm.dpm;
312         uint32_t ttb = 0;       /*  default ttb0 */
313         if (armv8->armv8_mmu.ttbr1_used == -1)
314                 armv8_read_ttbcr(target);
315         if ((armv8->armv8_mmu.ttbr1_used) &&
316                 (va > (0xffffffff & armv8->armv8_mmu.ttbr0_mask))) {
317                 /*  select ttb 1 */
318                 ttb = 1;
319         }
320         retval = dpm->prepare(dpm);
321         if (retval != ERROR_OK)
322                 goto done;
323
324         /*  MRC p15,0,<Rt>,c2,c0,ttb */
325         retval = dpm->instr_read_data_r0(dpm,
326                         ARMV4_5_MRC(15, 0, 0, 2, 0, ttb),
327                         &ttb);
328         if (retval != ERROR_OK)
329                 return retval;
330         retval = armv8->armv8_mmu.read_physical_memory(target,
331                         (ttb & 0xffffc000) | ((va & 0xfff00000) >> 18),
332                         4, 1, (uint8_t *)&first_lvl_descriptor);
333         if (retval != ERROR_OK)
334                 return retval;
335         first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)
336                         &first_lvl_descriptor);
337         /*  reuse armv4_5 piece of code, specific armv8 changes may come later */
338         LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor);
339
340         if ((first_lvl_descriptor & 0x3) == 0) {
341                 LOG_ERROR("Address translation failure");
342                 return ERROR_TARGET_TRANSLATION_FAULT;
343         }
344
345
346         if ((first_lvl_descriptor & 0x3) == 2) {
347                 /* section descriptor */
348                 *val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff);
349                 return ERROR_OK;
350         }
351
352         if ((first_lvl_descriptor & 0x3) == 1) {
353                 /* coarse page table */
354                 retval = armv8->armv8_mmu.read_physical_memory(target,
355                                 (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10),
356                                 4, 1, (uint8_t *)&second_lvl_descriptor);
357                 if (retval != ERROR_OK)
358                         return retval;
359         } else if ((first_lvl_descriptor & 0x3) == 3)   {
360                 /* fine page table */
361                 retval = armv8->armv8_mmu.read_physical_memory(target,
362                                 (first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8),
363                                 4, 1, (uint8_t *)&second_lvl_descriptor);
364                 if (retval != ERROR_OK)
365                         return retval;
366         }
367
368         second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)
369                         &second_lvl_descriptor);
370
371         LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor);
372
373         if ((second_lvl_descriptor & 0x3) == 0) {
374                 LOG_ERROR("Address translation failure");
375                 return ERROR_TARGET_TRANSLATION_FAULT;
376         }
377
378         if ((second_lvl_descriptor & 0x3) == 1) {
379                 /* large page descriptor */
380                 *val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff);
381                 return ERROR_OK;
382         }
383
384         if ((second_lvl_descriptor & 0x3) == 2) {
385                 /* small page descriptor */
386                 *val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff);
387                 return ERROR_OK;
388         }
389
390         if ((second_lvl_descriptor & 0x3) == 3) {
391                 *val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff);
392                 return ERROR_OK;
393         }
394
395         /* should not happen */
396         LOG_ERROR("Address translation failure");
397         return ERROR_TARGET_TRANSLATION_FAULT;
398
399 done:
400         return retval;
401 }
402
403 /*  V8 method VA TO PA  */
404 int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
405         target_addr_t *val, int meminfo)
406 {
407         return ERROR_OK;
408 }
409
410 static int armv8_handle_inner_cache_info_command(struct command_context *cmd_ctx,
411         struct armv8_cache_common *armv8_cache)
412 {
413         if (armv8_cache->ctype == -1) {
414                 command_print(cmd_ctx, "cache not yet identified");
415                 return ERROR_OK;
416         }
417
418         command_print(cmd_ctx,
419                 "D-Cache: linelen %" PRIi32 ", associativity %" PRIi32 ", nsets %" PRIi32 ", cachesize %" PRId32 " KBytes",
420                 armv8_cache->d_u_size.linelen,
421                 armv8_cache->d_u_size.associativity,
422                 armv8_cache->d_u_size.nsets,
423                 armv8_cache->d_u_size.cachesize);
424
425         command_print(cmd_ctx,
426                 "I-Cache: linelen %" PRIi32 ", associativity %" PRIi32 ", nsets %" PRIi32 ", cachesize %" PRId32 " KBytes",
427                 armv8_cache->i_size.linelen,
428                 armv8_cache->i_size.associativity,
429                 armv8_cache->i_size.nsets,
430                 armv8_cache->i_size.cachesize);
431
432         return ERROR_OK;
433 }
434
435 static int _armv8_flush_all_data(struct target *target)
436 {
437         struct armv8_common *armv8 = target_to_armv8(target);
438         struct arm_dpm *dpm = armv8->arm.dpm;
439         struct armv8_cachesize *d_u_size =
440                 &(armv8->armv8_mmu.armv8_cache.d_u_size);
441         int32_t c_way, c_index = d_u_size->index;
442         int retval;
443         /*  check that cache data is on at target halt */
444         if (!armv8->armv8_mmu.armv8_cache.d_u_cache_enabled) {
445                 LOG_INFO("flushed not performed :cache not on at target halt");
446                 return ERROR_OK;
447         }
448         retval = dpm->prepare(dpm);
449         if (retval != ERROR_OK)
450                 goto done;
451         do {
452                 c_way = d_u_size->way;
453                 do {
454                         uint32_t value = (c_index << d_u_size->index_shift)
455                                 | (c_way << d_u_size->way_shift);
456                         /*  DCCISW */
457                         /* LOG_INFO ("%d %d %x",c_way,c_index,value); */
458                         retval = dpm->instr_write_data_r0(dpm,
459                                         ARMV4_5_MCR(15, 0, 0, 7, 14, 2),
460                                         value);
461                         if (retval != ERROR_OK)
462                                 goto done;
463                         c_way -= 1;
464                 } while (c_way >= 0);
465                 c_index -= 1;
466         } while (c_index >= 0);
467         return retval;
468 done:
469         LOG_ERROR("flushed failed");
470         dpm->finish(dpm);
471         return retval;
472 }
473
474 static int  armv8_flush_all_data(struct target *target)
475 {
476         int retval = ERROR_FAIL;
477         /*  check that armv8_cache is correctly identify */
478         struct armv8_common *armv8 = target_to_armv8(target);
479         if (armv8->armv8_mmu.armv8_cache.ctype == -1) {
480                 LOG_ERROR("trying to flush un-identified cache");
481                 return retval;
482         }
483
484         if (target->smp) {
485                 /*  look if all the other target have been flushed in order to flush level
486                  *  2 */
487                 struct target_list *head;
488                 struct target *curr;
489                 head = target->head;
490                 while (head != (struct target_list *)NULL) {
491                         curr = head->target;
492                         if (curr->state == TARGET_HALTED) {
493                                 LOG_INFO("Wait flushing data l1 on core %" PRId32, curr->coreid);
494                                 retval = _armv8_flush_all_data(curr);
495                         }
496                         head = head->next;
497                 }
498         } else
499                 retval = _armv8_flush_all_data(target);
500         return retval;
501 }
502
503 int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
504         struct armv8_cache_common *armv8_cache)
505 {
506         if (armv8_cache->ctype == -1) {
507                 command_print(cmd_ctx, "cache not yet identified");
508                 return ERROR_OK;
509         }
510
511         if (armv8_cache->display_cache_info)
512                 armv8_cache->display_cache_info(cmd_ctx, armv8_cache);
513         return ERROR_OK;
514 }
515
516 /*  retrieve core id cluster id  */
517 static int armv8_read_mpidr(struct target *target)
518 {
519         int retval = ERROR_FAIL;
520         struct armv8_common *armv8 = target_to_armv8(target);
521         struct arm_dpm *dpm = armv8->arm.dpm;
522         uint32_t mpidr;
523         retval = dpm->prepare(dpm);
524         if (retval != ERROR_OK)
525                 goto done;
526         /* MRC p15,0,<Rd>,c0,c0,5; read Multiprocessor ID register*/
527
528         retval = dpm->instr_read_data_r0(dpm,
529                         ARMV8_MRS(SYSTEM_MPIDR, 0),
530                         &mpidr);
531         if (retval != ERROR_OK)
532                 goto done;
533         if (mpidr & 1<<31) {
534                 armv8->multi_processor_system = (mpidr >> 30) & 1;
535                 armv8->cluster_id = (mpidr >> 8) & 0xf;
536                 armv8->cpu_id = mpidr & 0x3;
537                 LOG_INFO("%s cluster %x core %x %s", target_name(target),
538                         armv8->cluster_id,
539                         armv8->cpu_id,
540                         armv8->multi_processor_system == 0 ? "multi core" : "mono core");
541
542         } else
543                 LOG_ERROR("mpdir not in multiprocessor format");
544
545 done:
546         dpm->finish(dpm);
547         return retval;
548
549
550 }
551
552 int armv8_identify_cache(struct target *target)
553 {
554         /*  read cache descriptor */
555         int retval = ERROR_FAIL;
556         struct armv8_common *armv8 = target_to_armv8(target);
557         struct arm_dpm *dpm = armv8->arm.dpm;
558         uint32_t cache_selected, clidr;
559         uint32_t cache_i_reg, cache_d_reg;
560         struct armv8_cache_common *cache = &(armv8->armv8_mmu.armv8_cache);
561         if (!armv8->is_armv7r)
562                 armv8_read_ttbcr(target);
563         retval = dpm->prepare(dpm);
564
565         if (retval != ERROR_OK)
566                 goto done;
567         /*  retrieve CLIDR
568          *  mrc p15, 1, r0, c0, c0, 1           @ read clidr */
569         retval = dpm->instr_read_data_r0(dpm,
570                         ARMV4_5_MRC(15, 1, 0, 0, 0, 1),
571                         &clidr);
572         if (retval != ERROR_OK)
573                 goto done;
574         clidr = (clidr & 0x7000000) >> 23;
575         LOG_INFO("number of cache level %" PRIx32, (uint32_t)(clidr / 2));
576         if ((clidr / 2) > 1) {
577                 /* FIXME not supported present in cortex A8 and later */
578                 /*  in cortex A7, A15 */
579                 LOG_ERROR("cache l2 present :not supported");
580         }
581         /*  retrieve selected cache
582          *  MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */
583         retval = dpm->instr_read_data_r0(dpm,
584                         ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
585                         &cache_selected);
586         if (retval != ERROR_OK)
587                 goto done;
588
589         retval = armv8->arm.mrc(target, 15,
590                         2, 0,   /* op1, op2 */
591                         0, 0,   /* CRn, CRm */
592                         &cache_selected);
593         if (retval != ERROR_OK)
594                 goto done;
595         /* select instruction cache
596          *  MCR p15, 2,<Rd>, c0, c0, 0; Write CSSELR
597          *  [0]  : 1 instruction cache selection , 0 data cache selection */
598         retval = dpm->instr_write_data_r0(dpm,
599                         ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
600                         1);
601         if (retval != ERROR_OK)
602                 goto done;
603
604         /* read CCSIDR
605          * MRC P15,1,<RT>,C0, C0,0 ;on cortex A9 read CCSIDR
606          * [2:0] line size  001 eight word per line
607          * [27:13] NumSet 0x7f 16KB, 0xff 32Kbytes, 0x1ff 64Kbytes */
608         retval = dpm->instr_read_data_r0(dpm,
609                         ARMV4_5_MRC(15, 1, 0, 0, 0, 0),
610                         &cache_i_reg);
611         if (retval != ERROR_OK)
612                 goto done;
613
614         /*  select data cache*/
615         retval = dpm->instr_write_data_r0(dpm,
616                         ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
617                         0);
618         if (retval != ERROR_OK)
619                 goto done;
620
621         retval = dpm->instr_read_data_r0(dpm,
622                         ARMV4_5_MRC(15, 1, 0, 0, 0, 0),
623                         &cache_d_reg);
624         if (retval != ERROR_OK)
625                 goto done;
626
627         /*  restore selected cache  */
628         dpm->instr_write_data_r0(dpm,
629                 ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
630                 cache_selected);
631
632         if (retval != ERROR_OK)
633                 goto done;
634         dpm->finish(dpm);
635
636         /* put fake type */
637         cache->d_u_size.linelen = 16 << (cache_d_reg & 0x7);
638         cache->d_u_size.cachesize = (((cache_d_reg >> 13) & 0x7fff)+1)/8;
639         cache->d_u_size.nsets = (cache_d_reg >> 13) & 0x7fff;
640         cache->d_u_size.associativity = ((cache_d_reg >> 3) & 0x3ff) + 1;
641         /*  compute info for set way operation on cache */
642         cache->d_u_size.index_shift = (cache_d_reg & 0x7) + 4;
643         cache->d_u_size.index = (cache_d_reg >> 13) & 0x7fff;
644         cache->d_u_size.way = ((cache_d_reg >> 3) & 0x3ff);
645         cache->d_u_size.way_shift = cache->d_u_size.way + 1;
646         {
647                 int i = 0;
648                 while (((cache->d_u_size.way_shift >> i) & 1) != 1)
649                         i++;
650                 cache->d_u_size.way_shift = 32-i;
651         }
652 #if 0
653         LOG_INFO("data cache index %d << %d, way %d << %d",
654                         cache->d_u_size.index, cache->d_u_size.index_shift,
655                         cache->d_u_size.way,
656                         cache->d_u_size.way_shift);
657
658         LOG_INFO("data cache %d bytes %d KBytes asso %d ways",
659                         cache->d_u_size.linelen,
660                         cache->d_u_size.cachesize,
661                         cache->d_u_size.associativity);
662 #endif
663         cache->i_size.linelen = 16 << (cache_i_reg & 0x7);
664         cache->i_size.associativity = ((cache_i_reg >> 3) & 0x3ff) + 1;
665         cache->i_size.nsets = (cache_i_reg >> 13) & 0x7fff;
666         cache->i_size.cachesize = (((cache_i_reg >> 13) & 0x7fff)+1)/8;
667         /*  compute info for set way operation on cache */
668         cache->i_size.index_shift = (cache_i_reg & 0x7) + 4;
669         cache->i_size.index = (cache_i_reg >> 13) & 0x7fff;
670         cache->i_size.way = ((cache_i_reg >> 3) & 0x3ff);
671         cache->i_size.way_shift = cache->i_size.way + 1;
672         {
673                 int i = 0;
674                 while (((cache->i_size.way_shift >> i) & 1) != 1)
675                         i++;
676                 cache->i_size.way_shift = 32-i;
677         }
678 #if 0
679         LOG_INFO("instruction cache index %d << %d, way %d << %d",
680                         cache->i_size.index, cache->i_size.index_shift,
681                         cache->i_size.way, cache->i_size.way_shift);
682
683         LOG_INFO("instruction cache %d bytes %d KBytes asso %d ways",
684                         cache->i_size.linelen,
685                         cache->i_size.cachesize,
686                         cache->i_size.associativity);
687 #endif
688         /*  if no l2 cache initialize l1 data cache flush function function */
689         if (armv8->armv8_mmu.armv8_cache.flush_all_data_cache == NULL) {
690                 armv8->armv8_mmu.armv8_cache.display_cache_info =
691                         armv8_handle_inner_cache_info_command;
692                 armv8->armv8_mmu.armv8_cache.flush_all_data_cache =
693                         armv8_flush_all_data;
694         }
695         armv8->armv8_mmu.armv8_cache.ctype = 0;
696
697 done:
698         dpm->finish(dpm);
699         armv8_read_mpidr(target);
700         return retval;
701
702 }
703
704 int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
705 {
706         struct arm *arm = &armv8->arm;
707         arm->arch_info = armv8;
708         target->arch_info = &armv8->arm;
709         /*  target is useful in all function arm v4 5 compatible */
710         armv8->arm.target = target;
711         armv8->arm.common_magic = ARM_COMMON_MAGIC;
712         armv8->common_magic = ARMV8_COMMON_MAGIC;
713
714         arm->read_core_reg = armv8_read_core_reg;
715 #if 0
716         arm->write_core_reg = armv8_write_core_reg;
717 #endif
718
719         armv8->armv8_mmu.armv8_cache.l2_cache = NULL;
720         armv8->armv8_mmu.armv8_cache.ctype = -1;
721         armv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;
722         armv8->armv8_mmu.armv8_cache.display_cache_info = NULL;
723         return ERROR_OK;
724 }
725
726 int armv8_arch_state(struct target *target)
727 {
728         static const char * const state[] = {
729                 "disabled", "enabled"
730         };
731
732         struct armv8_common *armv8 = target_to_armv8(target);
733         struct arm *arm = &armv8->arm;
734
735         if (armv8->common_magic != ARMV8_COMMON_MAGIC) {
736                 LOG_ERROR("BUG: called for a non-Armv8 target");
737                 return ERROR_COMMAND_SYNTAX_ERROR;
738         }
739
740         arm_arch_state(target);
741
742         if (armv8->is_armv7r) {
743                 LOG_USER("D-Cache: %s, I-Cache: %s",
744                         state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
745                         state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
746         } else {
747                 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
748                         state[armv8->armv8_mmu.mmu_enabled],
749                         state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
750                         state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
751         }
752
753         if (arm->core_mode == ARM_MODE_ABT)
754                 armv8_show_fault_registers(target);
755         if (target->debug_reason == DBG_REASON_WATCHPOINT)
756                 LOG_USER("Watchpoint triggered at PC %#08x",
757                         (unsigned) armv8->dpm.wp_pc);
758
759         return ERROR_OK;
760 }
761
762 static const struct {
763         unsigned id;
764         const char *name;
765         unsigned bits;
766         enum reg_type type;
767         const char *group;
768         const char *feature;
769 } armv8_regs[] = {
770         { ARMV8_R0,  "x0",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
771         { ARMV8_R1,  "x1",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
772         { ARMV8_R2,  "x2",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
773         { ARMV8_R3,  "x3",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
774         { ARMV8_R4,  "x4",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
775         { ARMV8_R5,  "x5",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
776         { ARMV8_R6,  "x6",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
777         { ARMV8_R7,  "x7",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
778         { ARMV8_R8,  "x8",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
779         { ARMV8_R9,  "x9",  64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
780         { ARMV8_R10, "x10", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
781         { ARMV8_R11, "x11", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
782         { ARMV8_R12, "x12", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
783         { ARMV8_R13, "x13", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
784         { ARMV8_R14, "x14", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
785         { ARMV8_R15, "x15", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
786         { ARMV8_R16, "x16", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
787         { ARMV8_R17, "x17", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
788         { ARMV8_R18, "x18", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
789         { ARMV8_R19, "x19", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
790         { ARMV8_R20, "x20", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
791         { ARMV8_R21, "x21", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
792         { ARMV8_R22, "x22", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
793         { ARMV8_R23, "x23", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
794         { ARMV8_R24, "x24", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
795         { ARMV8_R25, "x25", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
796         { ARMV8_R26, "x26", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
797         { ARMV8_R27, "x27", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
798         { ARMV8_R28, "x28", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
799         { ARMV8_R29, "x29", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
800         { ARMV8_R30, "x30", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
801
802         { ARMV8_R31, "sp", 64, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core" },
803         { ARMV8_PC,  "pc", 64, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core" },
804
805         { ARMV8_xPSR, "CPSR", 64, REG_TYPE_INT, "general", "org.gnu.gdb.aarch64.core" },
806 };
807
808 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
809
810
811 static int armv8_get_core_reg(struct reg *reg)
812 {
813         int retval;
814         struct arm_reg *armv8_reg = reg->arch_info;
815         struct target *target = armv8_reg->target;
816         struct arm *arm = target_to_arm(target);
817
818         if (target->state != TARGET_HALTED)
819                 return ERROR_TARGET_NOT_HALTED;
820
821         retval = arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);
822
823         return retval;
824 }
825
826 static int armv8_set_core_reg(struct reg *reg, uint8_t *buf)
827 {
828         struct arm_reg *armv8_reg = reg->arch_info;
829         struct target *target = armv8_reg->target;
830         uint64_t value = buf_get_u64(buf, 0, 64);
831
832         if (target->state != TARGET_HALTED)
833                 return ERROR_TARGET_NOT_HALTED;
834
835         buf_set_u64(reg->value, 0, 64, value);
836         reg->dirty = 1;
837         reg->valid = 1;
838
839         return ERROR_OK;
840 }
841
842 static const struct reg_arch_type armv8_reg_type = {
843         .get = armv8_get_core_reg,
844         .set = armv8_set_core_reg,
845 };
846
847 /** Builds cache of architecturally defined registers.  */
848 struct reg_cache *armv8_build_reg_cache(struct target *target)
849 {
850         struct armv8_common *armv8 = target_to_armv8(target);
851         struct arm *arm = &armv8->arm;
852         int num_regs = ARMV8_NUM_REGS;
853         struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
854         struct reg_cache *cache = malloc(sizeof(struct reg_cache));
855         struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
856         struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
857         struct reg_feature *feature;
858         int i;
859
860         /* Build the process context cache */
861         cache->name = "arm v8 registers";
862         cache->next = NULL;
863         cache->reg_list = reg_list;
864         cache->num_regs = num_regs;
865         (*cache_p) = cache;
866
867         for (i = 0; i < num_regs; i++) {
868                 arch_info[i].num = armv8_regs[i].id;
869                 arch_info[i].target = target;
870                 arch_info[i].arm = arm;
871
872                 reg_list[i].name = armv8_regs[i].name;
873                 reg_list[i].size = armv8_regs[i].bits;
874                 reg_list[i].value = calloc(1, 4);
875                 reg_list[i].dirty = 0;
876                 reg_list[i].valid = 0;
877                 reg_list[i].type = &armv8_reg_type;
878                 reg_list[i].arch_info = &arch_info[i];
879
880                 reg_list[i].group = armv8_regs[i].group;
881                 reg_list[i].number = i;
882                 reg_list[i].exist = true;
883                 reg_list[i].caller_save = true; /* gdb defaults to true */
884
885                 feature = calloc(1, sizeof(struct reg_feature));
886                 if (feature) {
887                         feature->name = armv8_regs[i].feature;
888                         reg_list[i].feature = feature;
889                 } else
890                         LOG_ERROR("unable to allocate feature list");
891
892                 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
893                 if (reg_list[i].reg_data_type)
894                         reg_list[i].reg_data_type->type = armv8_regs[i].type;
895                 else
896                         LOG_ERROR("unable to allocate reg type list");
897         }
898
899         arm->cpsr = reg_list + ARMV8_xPSR;
900         arm->pc = reg_list + ARMV8_PC;
901         arm->core_cache = cache;
902
903         return cache;
904 }
905
906 struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
907 {
908         struct reg *r;
909
910         if (regnum > 33)
911                 return NULL;
912
913         r = arm->core_cache->reg_list + regnum;
914         return r;
915 }
916
917 const struct command_registration armv8_command_handlers[] = {
918         {
919                 .chain = dap_command_handlers,
920         },
921         COMMAND_REGISTRATION_DONE
922 };
923
924
925 int armv8_get_gdb_reg_list(struct target *target,
926         struct reg **reg_list[], int *reg_list_size,
927         enum target_register_class reg_class)
928 {
929         struct arm *arm = target_to_arm(target);
930         int i;
931
932         switch (reg_class) {
933         case REG_CLASS_GENERAL:
934         case REG_CLASS_ALL:
935                 *reg_list_size = 34;
936                 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
937
938                 for (i = 0; i < *reg_list_size; i++)
939                                 (*reg_list)[i] = armv8_reg_current(arm, i);
940
941                 return ERROR_OK;
942                 break;
943
944         default:
945                 LOG_ERROR("not a valid register class type in query.");
946                 return ERROR_FAIL;
947                 break;
948         }
949 }