origen_arm_debug 0.8.4 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/commands.rb +2 -2
- data/config/version.rb +2 -2
- data/lib/origen_arm_debug/driver.rb +39 -38
- data/lib/origen_arm_debug/dut.rb +6 -4
- data/lib/origen_arm_debug/dut_jtag.rb +2 -1
- data/lib/origen_arm_debug/dut_swd.rb +5 -1
- data/lib/origen_arm_debug/mem_ap.rb +100 -244
- data/lib/origen_arm_debug/swj_dp.rb +159 -250
- data/lib/origen_arm_debug.rb +3 -3
- data/pattern/read_write_reg.rb +3 -3
- data/pattern/read_write_reg_jtag.rb +14 -7
- data/pattern/read_write_reg_swd.rb +15 -7
- data/templates/web/index.md.erb +5 -3
- metadata +6 -6
@@ -3,121 +3,98 @@ module OrigenARMDebug
|
|
3
3
|
# a top-level protocol be defined as well as a top-level instantiation of an
|
4
4
|
# SWJ-DP object.
|
5
5
|
class MemAP
|
6
|
-
|
7
|
-
MEM_ADDR_CSW = 0x00000000
|
8
|
-
MEM_ADDR_TAR = 0x00000004
|
9
|
-
MEM_ADDR_DRW = 0x0000000C
|
10
|
-
MEM_ADDR_BD0 = 0x00000010
|
11
|
-
MEM_ADDR_BD1 = 0x00000014
|
12
|
-
MEM_ADDR_BD2 = 0x00000018
|
13
|
-
MEM_ADDR_BD3 = 0x0000001C
|
14
|
-
MEM_ADDR_CFG = 0x000000F4
|
15
|
-
MEM_ADDR_BASE = 0x000000F8
|
16
|
-
MEM_ADDR_IDR = 0x000000FC
|
17
|
-
|
18
|
-
# Returns the parent object that instantiated the driver
|
19
|
-
attr_reader :owner
|
6
|
+
include Origen::Model
|
20
7
|
|
21
8
|
# Initialize class variables
|
22
9
|
#
|
23
|
-
# @param [Object] owner Parent object
|
24
10
|
# @param [Hash] options Options to customize the operation
|
25
11
|
#
|
26
12
|
# @example
|
27
13
|
# DUT.new.arm_debug.mem_ap
|
28
14
|
#
|
29
|
-
def initialize(
|
30
|
-
|
31
|
-
|
32
|
-
|
15
|
+
def initialize(options = {})
|
16
|
+
instantiate_registers
|
17
|
+
end
|
18
|
+
|
19
|
+
def instantiate_registers(options = {})
|
20
|
+
# ARM Debug Interface v5.1
|
21
|
+
reg :csw, 0x00, size: 32, reset: 0x00000000 do |reg|
|
22
|
+
reg.bit 31, :dbg_sw_enable
|
23
|
+
reg.bit 30..24, :prot
|
24
|
+
reg.bit 23, :spiden
|
25
|
+
reg.bit 11..8, :mode
|
26
|
+
reg.bit 7, :tr_in_prog
|
27
|
+
reg.bit 6, :device_en
|
28
|
+
reg.bit 5..4, :addr_inc, reset: 0b00
|
29
|
+
reg.bit 2..0, :size, reset: 0b000
|
30
|
+
end
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
@current_tar = 0xffffffff
|
37
|
-
@current_dsw = 0x00000000
|
32
|
+
add_reg :tar, 0x04, 32, data: { pos: 0, bits: 32 }, reset: 0xffffffff
|
33
|
+
add_reg :drw, 0x0C, 32, data: { pos: 0, bits: 32 }, reset: 0x00000000
|
38
34
|
end
|
39
35
|
|
40
36
|
# Shortcut name to SWJ-DP Debug Port
|
41
37
|
def debug_port
|
42
|
-
|
38
|
+
parent.swj_dp
|
43
39
|
end
|
44
40
|
alias_method :dp, :debug_port
|
45
41
|
|
46
|
-
# Output some instance-specific information
|
47
|
-
def inspect
|
48
|
-
Origen.log.info '=' * 30
|
49
|
-
Origen.log.info ' MEM-AP INFO'
|
50
|
-
Origen.log.info " name: #{@name}"
|
51
|
-
Origen.log.info " base address: 0x#{@base_address.to_hex}"
|
52
|
-
Origen.log.info ''
|
53
|
-
Origen.log.debug " csw_reg_addr = 0x#{csw_reg_addr.to_hex}"
|
54
|
-
Origen.log.debug " tar_reg_addr = 0x#{tar_reg_addr.to_hex}"
|
55
|
-
Origen.log.debug " drw_reg_addr = 0x#{drw_reg_addr.to_hex}"
|
56
|
-
Origen.log.debug " bd0_reg_addr = 0x#{bd0_reg_addr.to_hex}"
|
57
|
-
Origen.log.debug " bd1_reg_addr = 0x#{bd1_reg_addr.to_hex}"
|
58
|
-
Origen.log.debug " bd2_reg_addr = 0x#{bd2_reg_addr.to_hex}"
|
59
|
-
Origen.log.debug " bd3_reg_addr = 0x#{bd3_reg_addr.to_hex}"
|
60
|
-
Origen.log.debug " cfg_reg_addr = 0x#{cfg_reg_addr.to_hex}"
|
61
|
-
Origen.log.debug " base_reg_addr = 0x#{base_reg_addr.to_hex}"
|
62
|
-
Origen.log.debug " idr_reg_addr = 0x#{idr_reg_addr.to_hex}"
|
63
|
-
end
|
64
|
-
|
65
42
|
# -----------------------------------------------------------------------------
|
66
43
|
# User API
|
67
44
|
# -----------------------------------------------------------------------------
|
68
|
-
def
|
45
|
+
def write_register(reg_or_val, options = {})
|
69
46
|
if reg_or_val.respond_to?(:data)
|
70
47
|
addr = reg_or_val.addr
|
71
|
-
|
72
|
-
options = { reg: reg_or_val }.merge(options)
|
48
|
+
data = reg_or_val.data
|
73
49
|
else
|
74
|
-
addr =
|
75
|
-
|
50
|
+
addr = options[:address]
|
51
|
+
data = reg_or_val
|
76
52
|
end
|
53
|
+
size = options[:size] || 32
|
77
54
|
|
78
|
-
|
79
|
-
options = { r_mask: 'mask', r_attempts: 1 }.merge(options)
|
80
|
-
msg = 'Arm Debug: Shift out data for reading'
|
55
|
+
msg = "Arm Debug: Shift in data to write: #{data.to_hex}"
|
81
56
|
options = { arm_debug_comment: msg }.merge(options)
|
82
|
-
size = options[:size]
|
83
57
|
|
84
58
|
set_size(size)
|
85
59
|
set_addr(addr)
|
86
|
-
|
87
|
-
|
60
|
+
reg(:drw).data = get_wdata(size, addr, data)
|
61
|
+
debug_port.write_ap(reg(:drw).address, reg(:drw).data, options)
|
88
62
|
increment_addr
|
89
63
|
|
90
|
-
cc "MEM-AP(#{@name}):
|
91
|
-
"addr=0x#{addr.to_s(16).rjust(size / 4, '0')}"
|
64
|
+
cc "MEM-AP(#{@name}): WR-#{size.to_s(10)}: "\
|
65
|
+
"addr=0x#{addr.to_s(16).rjust(size / 4, '0')}, "\
|
66
|
+
"data=0x#{reg(:drw).data.to_s(16).rjust(size / 4, '0')}"
|
92
67
|
end
|
93
68
|
|
94
|
-
def
|
69
|
+
def read_register(reg_or_val, options = {})
|
95
70
|
if reg_or_val.respond_to?(:data)
|
96
71
|
addr = reg_or_val.addr
|
97
|
-
|
98
|
-
options =
|
72
|
+
data = reg_or_val.data
|
73
|
+
options[:mask] = reg_or_val.enable_mask(:read)
|
74
|
+
options[:store] = reg_or_val.enable_mask(:store)
|
99
75
|
else
|
100
|
-
addr =
|
101
|
-
|
76
|
+
addr = options[:address]
|
77
|
+
data = reg_or_val
|
102
78
|
end
|
103
|
-
|
104
|
-
options = { w_attempts: 1 }.merge(options)
|
105
|
-
msg = "Arm Debug: Shift in data to write: #{wdata.to_hex}"
|
106
|
-
options = { arm_debug_comment: msg }.merge(options)
|
107
|
-
size = options[:size]
|
79
|
+
size = options[:size] || 32
|
108
80
|
|
81
|
+
msg = 'Arm Debug: Shift out data for reading'
|
82
|
+
options = { arm_debug_comment: msg }.merge(options)
|
109
83
|
set_size(size)
|
110
84
|
set_addr(addr)
|
111
|
-
|
112
|
-
debug_port.
|
85
|
+
reg(:drw).data = get_rdata(size, addr, data)
|
86
|
+
debug_port.read_ap(reg(:drw).address, reg(:drw).data, options)
|
113
87
|
increment_addr
|
114
88
|
|
115
|
-
cc "MEM-AP(#{@name}):
|
116
|
-
"addr=0x#{addr.to_s(16).rjust(size / 4, '0')}
|
117
|
-
"data=0x#{wdata.to_s(16).rjust(size / 4, '0')}"
|
89
|
+
cc "MEM-AP(#{@name}): R-#{size.to_s(10)}: "\
|
90
|
+
"addr=0x#{addr.to_s(16).rjust(size / 4, '0')}"
|
118
91
|
end
|
119
92
|
|
120
|
-
#
|
93
|
+
# -----------------------------------------------------------------------------
|
94
|
+
# Legacy Support (to be phased out)
|
95
|
+
# -----------------------------------------------------------------------------
|
96
|
+
|
97
|
+
# Method to read from a mem_ap register (DEPRECATED)
|
121
98
|
#
|
122
99
|
# @param [Integer] addr Address of register to be read from
|
123
100
|
# @param [Hash] options Options to customize the operation
|
@@ -134,23 +111,23 @@ module OrigenARMDebug
|
|
134
111
|
#
|
135
112
|
# Returns nothing.
|
136
113
|
def read(addr, options = {})
|
137
|
-
|
138
|
-
|
139
|
-
msg
|
140
|
-
options = { arm_debug_comment: msg }.merge(options)
|
141
|
-
size = options[:size]
|
142
|
-
|
143
|
-
set_size(size)
|
144
|
-
set_addr(addr)
|
145
|
-
debug_port.read_ap(drw_reg_addr, options)
|
146
|
-
rdata = get_rdata(size, addr, 0)
|
147
|
-
increment_addr
|
114
|
+
# Warn caller that this method is being deprecated
|
115
|
+
msg = 'Use mem_ap.read_register(reg_or_val, options) instead of read(addr, options)'
|
116
|
+
Origen.deprecate msg
|
148
117
|
|
149
|
-
|
150
|
-
|
118
|
+
# Convert old style (addr, options) to (data, options) before passing on to new method
|
119
|
+
data = options.delete(:edata) || 0x00000000
|
120
|
+
mask = options.delete(:r_mask) || 0xFFFFFFFF
|
121
|
+
options = { address: addr, mask: mask }.merge(options)
|
122
|
+
if mask == 'store'
|
123
|
+
options = { store: 0xFFFFFFFF }.merge(options)
|
124
|
+
read_register(data, options)
|
125
|
+
else
|
126
|
+
read_register(data, options)
|
127
|
+
end
|
151
128
|
end
|
152
129
|
|
153
|
-
# Method to write to a mem_ap register
|
130
|
+
# Method to write to a mem_ap register (DEPRECATED)
|
154
131
|
#
|
155
132
|
# @param [Integer] addr Address of register to be read from
|
156
133
|
# @param [Integer] wdata Data to be written
|
@@ -161,24 +138,17 @@ module OrigenARMDebug
|
|
161
138
|
#
|
162
139
|
# Returns nothing.
|
163
140
|
def write(addr, wdata, options = {});
|
164
|
-
|
165
|
-
|
166
|
-
msg
|
167
|
-
options = { arm_debug_comment: msg }.merge(options)
|
168
|
-
size = options[:size]
|
169
|
-
|
170
|
-
set_size(size)
|
171
|
-
set_addr(addr)
|
172
|
-
wdata = get_wdata(size, addr, wdata)
|
173
|
-
debug_port.write_ap(drw_reg_addr, wdata, options)
|
174
|
-
increment_addr
|
141
|
+
# Warn caller that this method is being deprecated
|
142
|
+
msg = 'Use mem_ap.write_register(reg_or_val, options) instead of write(addr, wdata, options)'
|
143
|
+
Origen.deprecate msg
|
175
144
|
|
176
|
-
|
177
|
-
|
178
|
-
|
145
|
+
# Convert old style (addr, wdata, options) to (data, options) before passing on to new method
|
146
|
+
data = wdata
|
147
|
+
options = { address: addr }.merge(options)
|
148
|
+
write_register(data, options)
|
179
149
|
end
|
180
150
|
|
181
|
-
# Method to write and then read from a mem_ap register (
|
151
|
+
# Method to write and then read from a mem_ap register (DEPRECATED)
|
182
152
|
#
|
183
153
|
# @param [Integer] addr Address of register to be read from
|
184
154
|
# @param [Integer] wdata Data to be written
|
@@ -196,77 +166,18 @@ module OrigenARMDebug
|
|
196
166
|
#
|
197
167
|
# Returns nothing.
|
198
168
|
def write_read(addr, wdata, options = {})
|
199
|
-
options = { size: 32 }.merge(options)
|
200
|
-
options = { edata: 0x00000000, r_mask: 0xffffffff, actual: 0x00000000 }.merge(options)
|
201
|
-
options = { w_attempts: 1, r_attempts: 1 }.merge(options)
|
202
|
-
size = options[:size]
|
203
|
-
|
204
|
-
write(addr, wdata, options)
|
205
|
-
options[:edata] = wdata & options[:r_mask] if options[:edata] == 0x00000000
|
206
|
-
read(addr, options)
|
207
|
-
actual = wdata & options[:r_mask]
|
208
|
-
|
209
|
-
cc "MEM-AP(#{@name}): WR-#{size.to_s(10)}: "\
|
210
|
-
"addr=0x#{addr.to_s(16).rjust(size / 4, '0')}, "\
|
211
|
-
"wdata=0x#{wdata.to_s(16).rjust(size / 4, '0')}, "\
|
212
|
-
"read=0x#{actual.to_s(16).rjust(size / 4, '0')}, "\
|
213
|
-
"expect=0x#{options[:edata].to_s(16).rjust(size / 4, '0')}, "\
|
214
|
-
"mask=0x#{options[:r_mask].to_s(16).rjust(size / 4, '0')}"
|
215
|
-
end
|
216
|
-
|
217
|
-
# -----------------------------------------------------------------------------
|
218
|
-
# Legacy Support (to be phased out)
|
219
|
-
# -----------------------------------------------------------------------------
|
220
|
-
|
221
|
-
# Method to read from a mem_ap register (legacy)
|
222
|
-
#
|
223
|
-
# @param [Integer] addr Address of register to be read from
|
224
|
-
# @param [Integer] rdata This really does nothing since only care about value
|
225
|
-
# of options[:edata]
|
226
|
-
# @param [Hash] options Options to customize the operation
|
227
|
-
# Returns nothing.
|
228
|
-
def r(addr, rdata, options = {})
|
229
169
|
# Warn caller that this method is being deprecated
|
230
|
-
msg = 'Use mem_ap.
|
170
|
+
msg = 'Use mem_ap.write_read_register(reg_or_val, options) instead of write_read(addr, options)'
|
231
171
|
Origen.deprecate msg
|
232
172
|
|
233
|
-
#
|
234
|
-
|
235
|
-
|
173
|
+
# Convert old style (addr, wdata, options) to (data, options) before passing on to new method
|
174
|
+
data = wdata
|
175
|
+
mask = options.delete(:r_mask) || 0xFFFFFFFF
|
176
|
+
options = { address: addr, mask: mask }.merge(options)
|
177
|
+
write_register(data, options)
|
178
|
+
data = options[:edata] || wdata
|
179
|
+
read_register(data, options)
|
236
180
|
end
|
237
|
-
alias_method :R, :r
|
238
|
-
|
239
|
-
# Method to write to a mem_ap register (legacy)
|
240
|
-
#
|
241
|
-
# @param [Integer] addr Address of register to be written to
|
242
|
-
# @param [Integer] wdata Data to be written
|
243
|
-
# @param [Hash] options Options to customize the operation
|
244
|
-
# Returns nothing.
|
245
|
-
def w(addr, wdata, options = {})
|
246
|
-
# Warn caller that this method is being deprecated
|
247
|
-
msg = 'Use mem_ap.write(addr, wdata, options) instead of W(addr, wdata, options)'
|
248
|
-
Origen.deprecate msg
|
249
|
-
|
250
|
-
# Patch arguments and send to new method
|
251
|
-
write(addr, wdata, options)
|
252
|
-
end
|
253
|
-
alias_method :W, :w
|
254
|
-
|
255
|
-
# Method to write and then read from a mem_ap register (legacy)
|
256
|
-
#
|
257
|
-
# @param [Integer] addr Address of register to be read from
|
258
|
-
# @param [Integer] wdata Data to be written
|
259
|
-
# @param [Hash] options Options to customize the operation
|
260
|
-
# Returns nothing.
|
261
|
-
def wr(addr, wdata, options = {})
|
262
|
-
# Warn caller that this method is being deprecated
|
263
|
-
msg = 'Use mem_ap.write_read(addr, wdata, options) instead of WR(addr, wdata, options)'
|
264
|
-
Origen.deprecate msg
|
265
|
-
|
266
|
-
# Patch arguments and send to new method
|
267
|
-
write_read(addr, wdata, options)
|
268
|
-
end
|
269
|
-
alias_method :WR, :wr
|
270
181
|
|
271
182
|
# -----------------------------------------------------------------------------
|
272
183
|
# Support Code
|
@@ -280,22 +191,19 @@ module OrigenARMDebug
|
|
280
191
|
# @param [Integer] size Size of data, supports 8-bit, 16-bit, and 32-bit
|
281
192
|
def set_size(size)
|
282
193
|
case size
|
283
|
-
when 8 then new_size =
|
284
|
-
when 16 then new_size =
|
285
|
-
when 32 then new_size =
|
286
|
-
else new_size = 0x00000002
|
194
|
+
when 8 then new_size = 0b00
|
195
|
+
when 16 then new_size = 0b01
|
196
|
+
when 32 then new_size = 0b10
|
287
197
|
end
|
288
198
|
|
289
|
-
if (
|
290
|
-
debug_port.read_ap(
|
291
|
-
|
199
|
+
if (reg(:csw).data == 0x00000000)
|
200
|
+
debug_port.read_ap(reg(:csw).address, reg(:csw).data, mask: 0x00000000)
|
201
|
+
reg(:csw).data = 0x23000040
|
292
202
|
end
|
293
203
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
debug_port.write_ap(csw_reg_addr, new_csw)
|
298
|
-
@current_csw = new_csw
|
204
|
+
if (reg(:csw).bits(:size).data != new_size)
|
205
|
+
reg(:csw).bits(:size).data = new_size
|
206
|
+
debug_port.write_ap(reg(:csw).address, reg(:csw).data)
|
299
207
|
end
|
300
208
|
end
|
301
209
|
|
@@ -306,29 +214,27 @@ module OrigenARMDebug
|
|
306
214
|
arm_debug_comment = "Arm Debug: Shift in read/write address: #{addr.to_hex}"
|
307
215
|
options = { arm_debug_comment: arm_debug_comment }
|
308
216
|
|
309
|
-
if (
|
310
|
-
debug_port.write_ap(
|
217
|
+
if (reg(:tar).data != addr)
|
218
|
+
debug_port.write_ap(reg(:tar).address, addr, options)
|
311
219
|
end
|
312
|
-
|
220
|
+
reg(:tar).data = addr;
|
313
221
|
end
|
314
222
|
|
315
223
|
# Increment the address for the next transaction.
|
316
224
|
def increment_addr
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
when
|
322
|
-
when 1 then @current_tar += 2 # Increment single
|
323
|
-
when 2 then @current_tar += 4 # Increment single
|
225
|
+
if reg(:csw).bits(:addr_inc).data == 1
|
226
|
+
case reg(:csw).bits(:size)
|
227
|
+
when 0 then reg(:tar).data += 1 # Increment single
|
228
|
+
when 1 then reg(:tar).data += 2 # Increment single
|
229
|
+
when 2 then reg(:tar).data += 4 # Increment single
|
324
230
|
end
|
325
|
-
elsif (
|
326
|
-
|
231
|
+
elsif reg(:csw).bits(:addr_inc).data == 2
|
232
|
+
reg(:tar).data += 4 # Increment packed
|
327
233
|
end
|
328
234
|
|
329
|
-
if
|
235
|
+
if reg(:csw).bits(:addr_inc) && ((reg(:tar).data & 0xfffffc00) == 0xffffffff)
|
330
236
|
# reset tar when attempting to increment past 1kB boundary
|
331
|
-
|
237
|
+
reg(:tar).data = 0xffffffff
|
332
238
|
end
|
333
239
|
end
|
334
240
|
|
@@ -383,55 +289,5 @@ module OrigenARMDebug
|
|
383
289
|
end
|
384
290
|
wdata
|
385
291
|
end
|
386
|
-
|
387
|
-
# Returns address of CSW register for this mem-ap instance
|
388
|
-
def csw_reg_addr
|
389
|
-
MEM_ADDR_CSW + @base_address
|
390
|
-
end
|
391
|
-
|
392
|
-
# Returns address of TAR register for this mem-ap instance
|
393
|
-
def tar_reg_addr
|
394
|
-
MEM_ADDR_TAR + @base_address
|
395
|
-
end
|
396
|
-
|
397
|
-
# Returns address of DRW register for this mem-ap instance
|
398
|
-
def drw_reg_addr
|
399
|
-
MEM_ADDR_DRW + @base_address
|
400
|
-
end
|
401
|
-
|
402
|
-
# Returns address of BD0 register for this mem-ap instance
|
403
|
-
def bd0_reg_addr
|
404
|
-
MEM_ADDR_BD0 + @base_address
|
405
|
-
end
|
406
|
-
|
407
|
-
# Returns address of BD1 register for this mem-ap instance
|
408
|
-
def bd1_reg_addr
|
409
|
-
MEM_ADDR_BD1 + @base_address
|
410
|
-
end
|
411
|
-
|
412
|
-
# Returns address of BD2 register for this mem-ap instance
|
413
|
-
def bd2_reg_addr
|
414
|
-
MEM_ADDR_BD2 + @base_address
|
415
|
-
end
|
416
|
-
|
417
|
-
# Returns address of BD3 register for this mem-ap instance
|
418
|
-
def bd3_reg_addr
|
419
|
-
MEM_ADDR_BD3 + @base_address
|
420
|
-
end
|
421
|
-
|
422
|
-
# Returns address of CFG register for this mem-ap instance
|
423
|
-
def cfg_reg_addr
|
424
|
-
MEM_ADDR_CFG + @base_address
|
425
|
-
end
|
426
|
-
|
427
|
-
# Returns address of BASE register for this mem-ap instance
|
428
|
-
def base_reg_addr
|
429
|
-
MEM_ADDR_BASE + @base_address
|
430
|
-
end
|
431
|
-
|
432
|
-
# Returns address of IDR register for this mem-ap instance
|
433
|
-
def idr_reg_addr
|
434
|
-
MEM_ADDR_IDR + @base_address
|
435
|
-
end
|
436
292
|
end
|
437
293
|
end
|