tcl/esp32s2: check memory protection on gdb attach
[fw/openocd] / tcl / memory.tcl
1 # SPDX-License-Identifier: GPL-2.0-or-later
2
3 # MEMORY
4 #
5 # All Memory regions have two components.
6 #    (1) A count of regions, in the form N_NAME
7 #    (2) An array within info about each region.
8 #
9 # The ARRAY
10 #
11 #       <NAME>(  RegionNumber ,  ATTRIBUTE )
12 #
13 # Where <NAME> is one of:
14 #
15 #     N_FLASH  & FLASH   (internal memory)
16 #     N_RAM    & RAM     (internal memory)
17 #     N_MMREGS & MMREGS  (for memory mapped registers)
18 #     N_XMEM   & XMEM    (off chip memory, ie: flash on cs0, sdram on cs2)
19 # or  N_UNKNOWN & UNKNOWN for things that do not exist.
20 #
21 # We have 1 unknown region.
22 set N_UNKNOWN 1
23 # All MEMORY regions must have these attributes
24 #     CS          - chip select (if internal, use -1)
25 set UNKNOWN(0,CHIPSELECT) -1
26 #     BASE        - base address in memory
27 set UNKNOWN(0,BASE)       0
28 #     LEN         - length in bytes
29 set UNKNOWN(0,LEN)        $CPU_MAX_ADDRESS
30 #     HUMAN       - human name of the region
31 set UNKNOWN(0,HUMAN) "unknown"
32 #     TYPE        - one of:
33 #                       flash, ram, mmr, unknown
34 #                    For harvard arch:
35 #                       iflash, dflash, iram, dram
36 set UNKNOWN(0,TYPE)       "unknown"
37 #     RWX         - access ablity
38 #                       unix style chmod bits
39 #                           0 - no access
40 #                           1 - execute
41 #                           2 - write
42 #                           4 - read
43 #                       hence: 7 - readwrite execute
44 set RWX_NO_ACCESS     0
45 set RWX_X_ONLY        $BIT0
46 set RWX_W_ONLY        $BIT1
47 set RWX_R_ONLY        $BIT2
48 set RWX_RW            [expr {$RWX_R_ONLY + $RWX_W_ONLY}]
49 set RWX_R_X           [expr {$RWX_R_ONLY + $RWX_X_ONLY}]
50 set RWX_RWX           [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}]
51 set UNKNOWN(0,RWX)     $RWX_NO_ACCESS
52
53 #     WIDTH       - access width
54 #                      8,16,32 [0 means ANY]
55 set ACCESS_WIDTH_NONE 0
56 set ACCESS_WIDTH_8    $BIT0
57 set ACCESS_WIDTH_16   $BIT1
58 set ACCESS_WIDTH_32   $BIT2
59 set ACCESS_WIDTH_ANY  [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}]
60 set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE
61
62 proc iswithin { ADDRESS BASE LEN } {
63     return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}]
64 }
65
66 proc address_info { ADDRESS } {
67
68     foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } {
69         if { info exists $WHERE } {
70             set lmt [set N_[set WHERE]]
71             for { set region 0 } { $region < $lmt } { incr region } {
72                 if { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } {
73                     return  "$WHERE $region";
74                 }
75             }
76         }
77     }
78
79     # Return the 'unknown'
80     return "UNKNOWN 0"
81 }
82
83 proc memread32 {ADDR} {
84     if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] {
85         return $foo
86     } else {
87         error "memread32: $msg"
88     }
89 }
90
91 proc memread16 {ADDR} {
92     if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] {
93         return $foo
94     } else {
95         error "memread16: $msg"
96     }
97 }
98
99 proc memread8 {ADDR} {
100     if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] {
101         return $foo
102     } else {
103         error "memread8: $msg"
104     }
105 }
106
107 proc memwrite32 {ADDR DATA} {
108     if ![ catch { write_memory $ADDR 32 $DATA } msg ] {
109         return $DATA
110     } else {
111         error "memwrite32: $msg"
112     }
113 }
114
115 proc memwrite16 {ADDR DATA} {
116     if ![ catch { write_memory $ADDR 16 $DATA } msg ] {
117         return $DATA
118     } else {
119         error "memwrite16: $msg"
120     }
121 }
122
123 proc memwrite8 {ADDR DATA} {
124     if ![ catch { write_memory $ADDR 8 $DATA } msg ] {
125         return $DATA
126     } else {
127         error "memwrite8: $msg"
128     }
129 }
130
131 proc memread32_phys {ADDR} {
132     if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] {
133         return $foo
134     } else {
135         error "memread32: $msg"
136     }
137 }
138
139 proc memread16_phys {ADDR} {
140     if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] {
141         return $foo
142     } else {
143         error "memread16: $msg"
144     }
145 }
146
147 proc memread8_phys {ADDR} {
148     if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] {
149         return $foo
150     } else {
151         error "memread8: $msg"
152     }
153 }
154
155 proc memwrite32_phys {ADDR DATA} {
156     if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] {
157         return $DATA
158     } else {
159         error "memwrite32: $msg"
160     }
161 }
162
163 proc memwrite16_phys {ADDR DATA} {
164     if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] {
165         return $DATA
166     } else {
167         error "memwrite16: $msg"
168     }
169 }
170
171 proc memwrite8_phys {ADDR DATA} {
172     if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] {
173         return $DATA
174     } else {
175         error "memwrite8: $msg"
176     }
177 }