openocd: fix SPDX tag format for files .c
[fw/openocd] / src / target / register.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4  *   Copyright (C) 2005 by Dominic Rath                                    *
5  *   Dominic.Rath@gmx.de                                                   *
6  *                                                                         *
7  *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *
8  *   oyvind.harboe@zylin.com                                               *
9  ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14
15 #include "register.h"
16 #include <helper/log.h>
17
18 /**
19  * @file
20  * Holds utilities to work with register caches.
21  *
22  * OpenOCD uses machine registers internally, and exposes them by name
23  * to Tcl scripts.  Sets of related registers are grouped into caches.
24  * For example, a CPU core will expose a set of registers, and there
25  * may be separate registers associated with debug or trace modules.
26  */
27
28 struct reg *register_get_by_number(struct reg_cache *first,
29                 uint32_t reg_num, bool search_all)
30 {
31         struct reg_cache *cache = first;
32
33         while (cache) {
34                 for (unsigned int i = 0; i < cache->num_regs; i++) {
35                         if (!cache->reg_list[i].exist)
36                                 continue;
37                         if (cache->reg_list[i].number == reg_num)
38                                 return &(cache->reg_list[i]);
39                 }
40
41                 if (!search_all)
42                         break;
43
44                 cache = cache->next;
45         }
46
47         return NULL;
48 }
49
50 struct reg *register_get_by_name(struct reg_cache *first,
51                 const char *name, bool search_all)
52 {
53         struct reg_cache *cache = first;
54
55         while (cache) {
56                 for (unsigned int i = 0; i < cache->num_regs; i++) {
57                         if (!cache->reg_list[i].exist)
58                                 continue;
59                         if (strcmp(cache->reg_list[i].name, name) == 0)
60                                 return &(cache->reg_list[i]);
61                 }
62
63                 if (!search_all)
64                         break;
65
66                 cache = cache->next;
67         }
68
69         return NULL;
70 }
71
72 struct reg_cache **register_get_last_cache_p(struct reg_cache **first)
73 {
74         struct reg_cache **cache_p = first;
75
76         if (*cache_p)
77                 while (*cache_p)
78                         cache_p = &((*cache_p)->next);
79         else
80                 return first;
81
82         return cache_p;
83 }
84
85 void register_unlink_cache(struct reg_cache **cache_p, const struct reg_cache *cache)
86 {
87         while (*cache_p && *cache_p != cache)
88                 cache_p = &((*cache_p)->next);
89         if (*cache_p)
90                 *cache_p = cache->next;
91 }
92
93 /** Marks the contents of the register cache as invalid (and clean). */
94 void register_cache_invalidate(struct reg_cache *cache)
95 {
96         struct reg *reg = cache->reg_list;
97
98         for (unsigned int n = cache->num_regs; n != 0; n--, reg++) {
99                 if (!reg->exist)
100                         continue;
101                 reg->valid = false;
102                 reg->dirty = false;
103         }
104 }
105
106 static int register_get_dummy_core_reg(struct reg *reg)
107 {
108         return ERROR_OK;
109 }
110
111 static int register_set_dummy_core_reg(struct reg *reg, uint8_t *buf)
112 {
113         reg->dirty = true;
114         reg->valid = true;
115
116         return ERROR_OK;
117 }
118
119 static const struct reg_arch_type dummy_type = {
120         .get = register_get_dummy_core_reg,
121         .set = register_set_dummy_core_reg,
122 };
123
124 void register_init_dummy(struct reg *reg)
125 {
126         reg->type = &dummy_type;
127 }