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
@@ -1,14 +1,7 @@
|
|
1
1
|
module OrigenARMDebug
|
2
2
|
# Object that defines API for performing Debug AP transations using SWD or JTAG
|
3
3
|
class SWJ_DP
|
4
|
-
include Origen::
|
5
|
-
|
6
|
-
# Returns the parent object that instantiated the driver, could be
|
7
|
-
# either a DUT object or a protocol abstraction
|
8
|
-
attr_reader :owner
|
9
|
-
|
10
|
-
# Protocol implemented at the top-level (i.e. SWD or JTAG)
|
11
|
-
attr_reader :imp
|
4
|
+
include Origen::Model
|
12
5
|
|
13
6
|
# Customizable delay for DUT-specific required cycles for write_ap transaction
|
14
7
|
# to complete
|
@@ -26,32 +19,20 @@ module OrigenARMDebug
|
|
26
19
|
|
27
20
|
# Initialize class variables
|
28
21
|
#
|
29
|
-
# @param [Object] owner Parent object
|
30
22
|
# @param [Hash] options Options to customize the operation
|
31
23
|
#
|
32
24
|
# @example
|
33
25
|
# # Create new SWD::Driver object
|
34
26
|
# DUT.new.arm_debug.swj_dp
|
35
27
|
#
|
36
|
-
def initialize(
|
37
|
-
@owner = owner
|
38
|
-
|
39
|
-
if implementation == :jtag || implementation == :swd
|
40
|
-
@imp = implementation
|
41
|
-
else
|
42
|
-
msg = "SWJ-DP: '#{implementation}' implementation not supported. JTAG and SWD only"
|
43
|
-
fail msg
|
44
|
-
end
|
45
|
-
|
28
|
+
def initialize(options = {})
|
46
29
|
@random_mode = :compress
|
47
|
-
|
48
30
|
@write_ap_dly = 8
|
49
31
|
@acc_access_dly = 7
|
50
|
-
|
51
32
|
@current_apaddr = 0
|
52
33
|
@orundetect = 0
|
53
34
|
|
54
|
-
add_reg :ir, 0x00, 4, data: { pos: 0, bits: 4 }
|
35
|
+
add_reg :ir, 0x00, 4, data: { pos: 0, bits: 4 } # ARM-JTAG Instruction Register
|
55
36
|
|
56
37
|
add_reg :dpacc, 0x00, 35, rnw: { pos: 0 }, # DP-Access Register (DPACC)
|
57
38
|
a: { pos: 1, bits: 2 },
|
@@ -81,59 +62,85 @@ module OrigenARMDebug
|
|
81
62
|
# Method to read from a Debug Port register
|
82
63
|
#
|
83
64
|
# @param [String] name Name of register to be read from
|
84
|
-
# Supports:
|
65
|
+
# Supports: :idcode,:abort,:ctrl_stat,:select,:rdbuff,:wcr,:resend
|
66
|
+
# @param [Integer] data Value to be read
|
85
67
|
# @param [Hash] options Options to customize the operation
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
68
|
+
def read_dp(name, data, options = {})
|
69
|
+
if protocol == :swd
|
70
|
+
case name
|
71
|
+
when :idcode, :ctrl_stat, :rdbuff, :wcr, :resend
|
72
|
+
dpacc_access(name, 1, random, options)
|
73
|
+
when :abort, :ctrl_stat
|
74
|
+
log.error "#{name} #{protocol.to_s.upcase}-DP register is write-only!"
|
75
|
+
else
|
76
|
+
log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
|
77
|
+
end
|
91
78
|
else
|
92
|
-
|
79
|
+
case name
|
80
|
+
when :idcode
|
81
|
+
set_ir(name)
|
82
|
+
jtag.write_dr(random, size: 32)
|
83
|
+
when :abort
|
84
|
+
log.error "#{name} #{protocol.to_s.upcase}-DP register is write-only!"
|
85
|
+
when :ctrl_stat, :select
|
86
|
+
dpacc_access(name, 1, random, options)
|
87
|
+
when :rdbuff
|
88
|
+
dpacc_access(name, 1, data, options)
|
89
|
+
else
|
90
|
+
log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
|
91
|
+
end
|
92
|
+
read_dp(:rdbuff, data, options) if name != :idcode && name != :rdbuff
|
93
93
|
end
|
94
|
-
msg = "#{
|
95
|
-
msg += ", expected=#{
|
94
|
+
msg = "#{protocol.to_s.upcase}-DP: R-32: name='#{name.to_s.upcase}'"
|
95
|
+
msg += ", expected=#{data.to_s(16).rjust(8, '0')}" # if name == :rdbuff
|
96
96
|
cc msg
|
97
97
|
end
|
98
98
|
|
99
|
-
# Method to read from a Debug Port register and compare for an expected value
|
100
|
-
#
|
101
|
-
# @param [String] name Name of register to be read from
|
102
|
-
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
103
|
-
# @param [Integer] edata Value to compare read data against
|
104
|
-
# @param [Hash] options Options to customize the operation
|
105
|
-
def read_expect_dp(name, edata, options = {})
|
106
|
-
options[:edata] = edata
|
107
|
-
read_dp(name, options)
|
108
|
-
end
|
109
|
-
|
110
99
|
# Method to write to a Debug Port register
|
111
100
|
#
|
112
101
|
# @param [String] name Name of register to be written to
|
113
|
-
# Supports:
|
114
|
-
# @param [Integer]
|
102
|
+
# Supports: :idcode,:abort,:ctrl_stat,:select,:rdbuff,:wcr,:resend
|
103
|
+
# @param [Integer] data Value to written
|
115
104
|
# @param [Hash] options Options to customize the operation
|
116
|
-
def write_dp(name,
|
117
|
-
|
118
|
-
|
119
|
-
|
105
|
+
def write_dp(name, data, options = {})
|
106
|
+
if protocol == :swd
|
107
|
+
case name
|
108
|
+
when :idcode, :rdbuff, :resend
|
109
|
+
log.error "#{name} #{protocol.to_s.upcase}-DP register is read-only!"
|
110
|
+
when :abort, :ctrl_stat, :select, :wcr
|
111
|
+
dpacc_access(name, 0, data, options)
|
112
|
+
else
|
113
|
+
log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
|
114
|
+
end
|
120
115
|
else
|
121
|
-
|
116
|
+
case name
|
117
|
+
when :idcode, :rdbuff
|
118
|
+
log.error "#{name} #{protocol.to_s.upcase}-DP register is read-only!"
|
119
|
+
when :abort, :ctrl_stat, :select
|
120
|
+
dpacc_access(name, 0, data, options)
|
121
|
+
else
|
122
|
+
log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
|
123
|
+
end
|
122
124
|
end
|
123
|
-
cc "#{
|
125
|
+
cc "#{protocol.to_s.upcase}-DP: W-32: name='#{name.to_s.upcase}', data=0x#{data.to_s(16).rjust(8, '0')}"
|
124
126
|
end
|
125
127
|
|
126
128
|
# Method to write to and then read from a Debug Port register
|
127
129
|
#
|
128
130
|
# @param [String] name Name of register to be written to and read from
|
129
|
-
# Supports:
|
130
|
-
# @param [Integer]
|
131
|
+
# Supports: :idcode,:abort,:ctrl_stat,:select,:rdbuff,:wcr,:resend
|
132
|
+
# @param [Integer] data Value to written
|
131
133
|
# @param [Hash] options Options to customize the operation
|
132
|
-
def write_read_dp(name,
|
133
|
-
write_dp(name,
|
134
|
-
|
134
|
+
def write_read_dp(name, data, options = {})
|
135
|
+
write_dp(name, data, options)
|
136
|
+
if options[:actual].nil?
|
137
|
+
read_dp(name, data, options)
|
138
|
+
else
|
139
|
+
rdata = options.delete(:actual)
|
140
|
+
read_dp(name, rdata, options)
|
141
|
+
end
|
135
142
|
|
136
|
-
cc "#{
|
143
|
+
cc "#{protocol.to_s.upcase}-DP: WR-32: name='#{name.to_s.upcase}', data=0x#{data.to_s(16).rjust(8, '0')}"
|
137
144
|
end
|
138
145
|
|
139
146
|
#-------------------------------------
|
@@ -145,24 +152,17 @@ module OrigenARMDebug
|
|
145
152
|
# @param [Integer] addr Address of register to be read from
|
146
153
|
# @param [Hash] options Options to customize the operation
|
147
154
|
# @option options [Integer] edata Value to compare read data against
|
148
|
-
def read_ap(addr, options = {})
|
155
|
+
def read_ap(addr, data, options = {})
|
149
156
|
rwb = 1
|
150
|
-
options = { r_attempts: 1 }.merge(options)
|
151
|
-
|
152
157
|
# Create another copy of options with select keys removed.
|
153
158
|
# This first read is junk so we do not want to store it or compare it.
|
154
159
|
junk_options = options.clone.delete_if do |key, val|
|
155
160
|
(key.eql?(:r_mask) && val.eql?('store')) || key.eql?(:compare_data) || key.eql?(:reg)
|
156
161
|
end
|
157
|
-
|
158
|
-
apacc_access(addr, rwb, random,
|
159
|
-
read_dp(
|
160
|
-
|
161
|
-
if @imp == :swd
|
162
|
-
cc "SW-AP: R-32: addr=0x#{addr.to_s(16).rjust(8, '0')}"
|
163
|
-
else
|
164
|
-
cc "JTAG-AP: R-32: addr=0x#{addr.to_s(16).rjust(8, '0')}"
|
165
|
-
end
|
162
|
+
junk_options[:mask] = 0x00000000
|
163
|
+
apacc_access(addr, rwb, random, junk_options)
|
164
|
+
read_dp(:rdbuff, data, options) # This is the real data
|
165
|
+
cc "#{protocol.to_s.upcase}-AP: R-32: addr=0x#{addr.to_s(16).rjust(8, '0')}"
|
166
166
|
end
|
167
167
|
|
168
168
|
# Method to read from a Access Port register and compare against specific value
|
@@ -170,50 +170,52 @@ module OrigenARMDebug
|
|
170
170
|
# @param [Integer] addr Address of register to be read from
|
171
171
|
# @param [Integer] edata Value to compare read data against
|
172
172
|
# @param [Hash] options Options to customize the operation
|
173
|
-
def read_expect_ap(addr,
|
174
|
-
|
175
|
-
read_ap(addr, options)
|
173
|
+
def read_expect_ap(addr, options = {})
|
174
|
+
# Warn caller that this method is being deprecated
|
175
|
+
msg = 'Use swj_dp.read_ap(addr, data, options) instead of read_expect_ap(addr, edata: 0xXXXXXXX)'
|
176
|
+
Origen.deprecate msg
|
177
|
+
|
178
|
+
edata = options[:edata] || 0x00000000
|
179
|
+
read_ap(addr, edata, options)
|
176
180
|
end
|
177
181
|
alias_method :wait_read_expect_ap, :read_expect_ap
|
178
182
|
|
179
183
|
# Method to write to a Access Port register
|
180
184
|
#
|
181
185
|
# @param [Integer] addr Address of register to be read from
|
182
|
-
# @param [Integer]
|
186
|
+
# @param [Integer] data Value to written
|
183
187
|
# @param [Hash] options Options to customize the operation
|
184
|
-
def write_ap(addr,
|
188
|
+
def write_ap(addr, data, options = {})
|
185
189
|
rwb = 0
|
186
|
-
options =
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
else
|
194
|
-
cc 'JTAG-AP: W-32: '\
|
195
|
-
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
196
|
-
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
197
|
-
end
|
190
|
+
options[:mask] = 0x00000000
|
191
|
+
# options = { w_attempts: 1 }.merge(options)
|
192
|
+
apacc_access(addr, rwb, data, options)
|
193
|
+
$tester.cycle(repeat: @write_ap_dly) if protocol == :jtag
|
194
|
+
cc "#{protocol.to_s.upcase}-AP: W-32: "\
|
195
|
+
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
196
|
+
"data=0x#{data.to_s(16).rjust(8, '0')}"
|
198
197
|
end
|
199
198
|
|
200
199
|
# Method to write to and then read from a Debug Port register
|
201
200
|
#
|
202
201
|
# @param [Integer] addr Address of register to be read from
|
203
|
-
# @param [Integer]
|
202
|
+
# @param [Integer] data Value to written
|
204
203
|
# @param [Hash] options Options to customize the operation
|
205
|
-
def write_read_ap(addr,
|
206
|
-
|
207
|
-
read_ap(addr, options)
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
204
|
+
def write_read_ap(addr, data, options = {})
|
205
|
+
# Warn caller that this method is being deprecated
|
206
|
+
msg = 'Use write_ap(addr, data, options); read_ap(addr, data, options) instead of write_read_ap'
|
207
|
+
Origen.deprecate msg
|
208
|
+
|
209
|
+
write_ap(addr, data, options)
|
210
|
+
if options[:edata].nil?
|
211
|
+
read_ap(addr, data, options)
|
212
212
|
else
|
213
|
-
|
214
|
-
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
215
|
-
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
213
|
+
read_ap(addr, options[:edata], options)
|
216
214
|
end
|
215
|
+
|
216
|
+
cc "#{protocol.to_s.upcase}: WR-32: "\
|
217
|
+
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
218
|
+
"data=0x#{data.to_s(16).rjust(8, '0')}"
|
217
219
|
end
|
218
220
|
|
219
221
|
private
|
@@ -222,115 +224,37 @@ module OrigenARMDebug
|
|
222
224
|
# DPACC Access Implementation-Specific methods
|
223
225
|
#-----------------------------------------------
|
224
226
|
|
225
|
-
# Method to read from a Debug Port register with SWD protocol
|
226
|
-
#
|
227
|
-
# @param [String] name Name of register to be read from
|
228
|
-
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
229
|
-
# @param [Hash] options Options to customize the operation
|
230
|
-
def read_dp_swd(name, options = {})
|
231
|
-
rwb = 1
|
232
|
-
case name
|
233
|
-
when 'IDCODE' then dpacc_access(name, rwb, random, options)
|
234
|
-
when 'ABORT' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is write-only!"
|
235
|
-
when 'CTRL/STAT' then dpacc_access(name, rwb, random, options)
|
236
|
-
when 'SELECT' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is write-only!"
|
237
|
-
when 'RDBUFF' then dpacc_access(name, rwb, random, options)
|
238
|
-
when 'WCR' then dpacc_access(name, rwb, random, options)
|
239
|
-
when 'RESEND' then dpacc_access(name, rwb, random, options)
|
240
|
-
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
# Method to read from a Debug Port register with JTAG protocol
|
245
|
-
#
|
246
|
-
# @param [String] name Name of register to be read from
|
247
|
-
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
248
|
-
# @param [Hash] options Options to customize the operation
|
249
|
-
def read_dp_jtag(name, options = {})
|
250
|
-
rwb = 1
|
251
|
-
set_ir(name) if name == 'IDCODE'
|
252
|
-
case name
|
253
|
-
when 'IDCODE' then jtag.write_dr(random, size: 32)
|
254
|
-
when 'ABORT' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is write-only!"
|
255
|
-
when 'CTRL/STAT' then dpacc_access(name, rwb, random, options)
|
256
|
-
when 'SELECT' then dpacc_access(name, rwb, random, options)
|
257
|
-
when 'RDBUFF' then dpacc_access(name, rwb, random, options)
|
258
|
-
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
259
|
-
end
|
260
|
-
read_dp('RDBUFF', options) if name != 'IDCODE' && name != 'RDBUFF'
|
261
|
-
end
|
262
|
-
|
263
|
-
# Method to write to a Debug Port register with SWD protocol
|
264
|
-
#
|
265
|
-
# @param [String] name Name of register to be read from
|
266
|
-
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
267
|
-
# @param [Integer] wdata Data to be written
|
268
|
-
# @param [Hash] options Options to customize the operation
|
269
|
-
def write_dp_swd(name, wdata, options = {})
|
270
|
-
rwb = 0
|
271
|
-
case name
|
272
|
-
when 'IDCODE' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
273
|
-
when 'ABORT' then dpacc_access(name, rwb, wdata, options)
|
274
|
-
when 'CTRL/STAT' then dpacc_access(name, rwb, wdata, options)
|
275
|
-
when 'SELECT' then dpacc_access(name, rwb, wdata, options)
|
276
|
-
when 'RDBUFF' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
277
|
-
when 'WCR' then dpacc_access(name, rwb, wdata, options)
|
278
|
-
when 'RESEND' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
279
|
-
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
# Method to write to a Debug Port register with JTAG protocol
|
284
|
-
#
|
285
|
-
# @param [String] name Name of register to be read from
|
286
|
-
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
287
|
-
# @param [Integer] wdata Data to be written
|
288
|
-
# @param [Hash] options Options to customize the operation
|
289
|
-
def write_dp_jtag(name, wdata, options = {})
|
290
|
-
rwb = 0
|
291
|
-
case name
|
292
|
-
when 'IDCODE' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
293
|
-
when 'ABORT' then dpacc_access(name, rwb, wdata, options)
|
294
|
-
when 'CTRL/STAT' then dpacc_access(name, rwb, wdata, options)
|
295
|
-
when 'SELECT' then dpacc_access(name, rwb, wdata, options)
|
296
|
-
when 'RDBUFF' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
297
|
-
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
227
|
# Method
|
302
228
|
#
|
303
229
|
# @param [Integer] name Name of register to be transacted
|
304
230
|
# @param [Integer] rwb Indicates read or write
|
305
|
-
# @param [Integer]
|
231
|
+
# @param [Integer] data Value of data to be written
|
306
232
|
# @param [Hash] options Options to customize the operation
|
307
|
-
def dpacc_access(name, rwb,
|
233
|
+
def dpacc_access(name, rwb, data, options = {})
|
308
234
|
addr = get_dp_addr(name)
|
309
|
-
|
310
|
-
if name == 'CTRL/STAT' && @imp == :swd
|
235
|
+
if name == :ctrl_stat && protocol == :swd
|
311
236
|
set_apselect(@current_apaddr & 0xFFFFFFFE, options)
|
312
237
|
end
|
313
|
-
set_ir(name) if
|
238
|
+
set_ir(name) if protocol == :jtag
|
314
239
|
options = { name: name }.merge(options)
|
315
|
-
acc_access(addr, rwb, 0,
|
240
|
+
acc_access(addr, rwb, 0, data, options)
|
316
241
|
end
|
317
242
|
|
318
243
|
# Method
|
319
244
|
#
|
320
245
|
# @param [Integer] addr Address of register to be transacted
|
321
246
|
# @param [Integer] rwb Indicates read or write
|
322
|
-
# @param [Integer]
|
323
|
-
# @param [Integer] rdata Value of data to be read back
|
247
|
+
# @param [Integer] data Value of data to be written
|
324
248
|
# @param [Hash] options Options to customize the operation
|
325
|
-
def apacc_access(addr, rwb,
|
249
|
+
def apacc_access(addr, rwb, data, options = {})
|
326
250
|
set_apselect((addr & 0xFFFFFFFE) | (@current_apaddr & 1), options)
|
327
|
-
if
|
251
|
+
if protocol == :swd
|
328
252
|
options.delete(:w_delay) if options.key?(:w_delay)
|
329
253
|
else
|
330
|
-
set_ir(
|
254
|
+
set_ir(:apacc)
|
331
255
|
end
|
332
|
-
options = { name:
|
333
|
-
acc_access((addr & 0xC), rwb, 1,
|
256
|
+
options = { name: :apacc }.merge(options)
|
257
|
+
acc_access((addr & 0xC), rwb, 1, data, options)
|
334
258
|
end
|
335
259
|
|
336
260
|
# Method
|
@@ -338,13 +262,13 @@ module OrigenARMDebug
|
|
338
262
|
# @param [Integer] addr Address of register to be transacted
|
339
263
|
# @param [Integer] rwb Indicates read or write
|
340
264
|
# @param [Integer] ap_dp Indicates Access Port or Debug Port
|
341
|
-
# @param [Integer]
|
265
|
+
# @param [Integer] data Value of data to be written
|
342
266
|
# @param [Hash] options Options to customize the operation
|
343
|
-
def acc_access(addr, rwb, ap_dp,
|
344
|
-
if
|
345
|
-
acc_access_swd(addr, rwb, ap_dp,
|
267
|
+
def acc_access(addr, rwb, ap_dp, data, options = {})
|
268
|
+
if protocol == :swd
|
269
|
+
acc_access_swd(addr, rwb, ap_dp, data, options)
|
346
270
|
else
|
347
|
-
acc_access_jtag(addr, rwb, ap_dp,
|
271
|
+
acc_access_jtag(addr, rwb, ap_dp, data, options)
|
348
272
|
end
|
349
273
|
end
|
350
274
|
|
@@ -353,20 +277,14 @@ module OrigenARMDebug
|
|
353
277
|
# @param [Integer] addr Address of register to be transacted
|
354
278
|
# @param [Integer] rwb Indicates read or write
|
355
279
|
# @param [Integer] ap_dp Indicates Access Port or Debug Port
|
356
|
-
# @param [Integer]
|
280
|
+
# @param [Integer] data Value of data to be written
|
357
281
|
# @param [Hash] options Options to customize the operation
|
358
|
-
def acc_access_swd(addr, rwb, ap_dp,
|
282
|
+
def acc_access_swd(addr, rwb, ap_dp, data, options = {})
|
359
283
|
_name = options.delete(:name)
|
360
284
|
if (rwb == 1)
|
361
|
-
|
362
|
-
swd.read(ap_dp, addr, options)
|
363
|
-
else
|
364
|
-
# make sure reg.addr = addr
|
365
|
-
Origen.log.error 'SWJ_DP ERROR: In acc_access_swd, addr does not match options[:reg].addr'
|
366
|
-
swd.read(ap_dp, options[:reg], options)
|
367
|
-
end
|
285
|
+
swd.read(ap_dp, addr, options)
|
368
286
|
else
|
369
|
-
swd.write(ap_dp, addr,
|
287
|
+
swd.write(ap_dp, addr, data, options)
|
370
288
|
end
|
371
289
|
options = { w_delay: 10 }.merge(options)
|
372
290
|
swd.swd_dio_to_0(options[:w_delay])
|
@@ -377,43 +295,25 @@ module OrigenARMDebug
|
|
377
295
|
# @param [Integer] addr Address of register to be transacted
|
378
296
|
# @param [Integer] rwb Indicates read or write
|
379
297
|
# @param [Integer] ap_dp Indicates Access Port or Debug Port
|
380
|
-
# @param [Integer]
|
298
|
+
# @param [Integer] data Value of data to be written
|
381
299
|
# @param [Hash] options Options to customize the operation
|
382
|
-
def acc_access_jtag(addr, rwb, ap_dp,
|
300
|
+
def acc_access_jtag(addr, rwb, ap_dp, data, options = {})
|
383
301
|
_name = options.delete(:name)
|
384
|
-
|
385
|
-
attempts = options[:r_attempts]
|
386
|
-
elsif !options[:w_attempts].nil?
|
387
|
-
attempts = options[:w_attempts]
|
388
|
-
else
|
389
|
-
attempts = 1
|
390
|
-
end
|
391
|
-
|
302
|
+
attempts = options[:attempts] || 1
|
392
303
|
attempts.times do
|
393
|
-
if _name ==
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
reg(:dpacc).bits(:data).data = options[:edata]
|
402
|
-
end
|
403
|
-
else
|
404
|
-
reg(:dpacc).bits(:data).data = options[:reg].data
|
405
|
-
(3..34).each do |i|
|
406
|
-
reg(:dpacc).bits(i).read if options[:reg].bits(i - 3).is_to_be_read?
|
407
|
-
end
|
408
|
-
(3..34).each do |i|
|
409
|
-
reg(:dpacc).bits(i).store if options[:reg].bits(i - 3).is_to_be_stored?
|
410
|
-
end
|
304
|
+
if _name == :rdbuff
|
305
|
+
reg(:dpacc).bits(:data).clear_flags
|
306
|
+
reg(:dpacc).bits(:data).write(data)
|
307
|
+
_mask = options[:mask] || 0xFFFFFFFF
|
308
|
+
_store = options[:store] || 0x00000000
|
309
|
+
0.upto(31) do |i|
|
310
|
+
reg(:dpacc).bits(:data)[i].read if _mask[i] == 1
|
311
|
+
reg(:dpacc).bits(:data)[i].store if _store[i] == 1
|
411
312
|
end
|
412
|
-
|
413
313
|
options = options.merge(size: reg(:dpacc).size)
|
414
314
|
jtag.read_dr(reg(:dpacc), options)
|
415
315
|
else
|
416
|
-
reg(:dpacc).bits(:data).write(
|
316
|
+
reg(:dpacc).bits(:data).write(data)
|
417
317
|
reg(:dpacc).bits(:a).write((addr & 0x0000000C) >> 2)
|
418
318
|
reg(:dpacc).bits(:rnw).write(rwb)
|
419
319
|
options = options.merge(size: reg(:dpacc).size)
|
@@ -428,14 +328,13 @@ module OrigenARMDebug
|
|
428
328
|
# @param [String] name Name of the register
|
429
329
|
def get_dp_addr(name)
|
430
330
|
case name
|
431
|
-
when
|
432
|
-
when
|
433
|
-
when
|
434
|
-
when
|
435
|
-
when
|
436
|
-
when
|
437
|
-
when
|
438
|
-
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
331
|
+
when :idcode then return 0x0
|
332
|
+
when :abort then return 0x0
|
333
|
+
when :ctrl_stat then return 0x4
|
334
|
+
when :select then return 0x8
|
335
|
+
when :rdbuff then return 0xC
|
336
|
+
when :wcr then return 0x4
|
337
|
+
when :resend then return 0x8
|
439
338
|
end
|
440
339
|
end
|
441
340
|
|
@@ -444,18 +343,14 @@ module OrigenARMDebug
|
|
444
343
|
# @param [String] name Name of the register to be interacted with
|
445
344
|
def set_ir(name)
|
446
345
|
case name
|
447
|
-
when
|
346
|
+
when :idcode
|
448
347
|
reg(:ir).write(0b1110) # JTAGC_ARM_IDCODE
|
449
|
-
when
|
348
|
+
when :abort
|
450
349
|
reg(:ir).write(0b1000) # JTAGC_ARM_ABORT
|
451
|
-
when
|
350
|
+
when :ctrl_stat, :select, :rdbuff
|
452
351
|
reg(:ir).write(0b1010) # JTAGC_ARM_DPACC
|
453
|
-
when
|
352
|
+
when :apacc
|
454
353
|
reg(:ir).write(0b1011) # JTAGC_ARM_APACC
|
455
|
-
when 'RESEND', 'WCR'
|
456
|
-
Origen.log.error "#{name} is a SW-DP only register"
|
457
|
-
else
|
458
|
-
Origen.log.error "Unknown JTAG-DP register name: #{name}"
|
459
354
|
end
|
460
355
|
jtag.write_ir(reg(:ir), size: reg(:ir).size)
|
461
356
|
end
|
@@ -466,14 +361,14 @@ module OrigenARMDebug
|
|
466
361
|
# will determine which Access Port is selected.
|
467
362
|
# @param [Hash] options Options to customize the operation
|
468
363
|
def set_apselect(addr, options = {})
|
469
|
-
if
|
364
|
+
if protocol == :swd
|
470
365
|
addr &= 0xff0000f1
|
471
366
|
else
|
472
367
|
addr &= 0xff0000f0
|
473
368
|
end
|
474
369
|
|
475
370
|
if (addr != @current_apaddr)
|
476
|
-
write_dp(
|
371
|
+
write_dp(:select, addr & 0xff0000ff, options)
|
477
372
|
end
|
478
373
|
@current_apaddr = addr
|
479
374
|
end
|
@@ -491,12 +386,26 @@ module OrigenARMDebug
|
|
491
386
|
|
492
387
|
# Provides shortname access to top-level jtag driver
|
493
388
|
def jtag
|
494
|
-
|
389
|
+
parent.parent.jtag
|
495
390
|
end
|
496
391
|
|
497
392
|
# Provides shortname access to top-level swd driver
|
498
393
|
def swd
|
499
|
-
|
394
|
+
parent.parent.swd
|
395
|
+
end
|
396
|
+
|
397
|
+
# Returns protocol implemented at the top-level (i.e. SWD or JTAG)
|
398
|
+
def protocol
|
399
|
+
if parent.parent.respond_to?(:swd)
|
400
|
+
implementation = :swd
|
401
|
+
elsif parent.parent.respond_to?(:jtag)
|
402
|
+
implementation = :jtag
|
403
|
+
end
|
404
|
+
implementation
|
405
|
+
end
|
406
|
+
|
407
|
+
def log
|
408
|
+
Origen.log
|
500
409
|
end
|
501
410
|
end
|
502
411
|
end
|
data/lib/origen_arm_debug.rb
CHANGED
data/pattern/read_write_reg.rb
CHANGED
@@ -24,10 +24,10 @@ Pattern.create do
|
|
24
24
|
$dut.write_register($dut.reg(:test))
|
25
25
|
|
26
26
|
$dut.arm_debug.mem_ap.read(0x10000004, edata: 0x00000000)
|
27
|
+
$dut.arm_debug.mem_ap.read(0x10000004, r_mask: 'store')
|
27
28
|
$dut.arm_debug.mem_ap.write(0x10000004, 0x55555555)
|
28
29
|
$dut.arm_debug.mem_ap.write_read(0x10000004, 0x55555555)
|
29
30
|
|
30
|
-
$dut.arm_debug.mem_ap
|
31
|
-
$dut.arm_debug.
|
32
|
-
$dut.arm_debug.alt_ahbapi.inspect
|
31
|
+
$dut.arm_debug.write_register(0x55555555, address: 0x10000004, ap: :mem_ap)
|
32
|
+
$dut.arm_debug.read_register(0x55555555, address: 0x10000004, ap: :mem_ap)
|
33
33
|
end
|
@@ -1,10 +1,17 @@
|
|
1
1
|
Pattern.create do
|
2
|
+
$dut_jtag = $dut
|
3
|
+
$dut_jtag.arm_debug.swj_dp.read_dp(:idcode, 0xba5eba11, mask: 0x00000000)
|
4
|
+
$dut_jtag.arm_debug.abs_if.read_dp(:idcode, 0xba5eba11)
|
5
|
+
$dut_jtag.arm_debug.dpapi.write_dp(:ctrl_stat, 0x50000000)
|
6
|
+
$dut_jtag.arm_debug.swj_dp.read_dp(:ctrl_stat, 0xf0000000)
|
7
|
+
$dut_jtag.arm_debug.apapi.read_ap(0x010000FC, 0x00000000, mask: 0x00000000)
|
8
|
+
$dut_jtag.arm_debug.swj_dp.write_ap(0x01000004, 0x10101010)
|
9
|
+
$dut_jtag.arm_debug.swj_dp.read_ap(0x01000004, 0x10101010)
|
2
10
|
|
3
|
-
|
4
|
-
$dut_jtag.arm_debug.swj_dp.
|
5
|
-
$dut_jtag.arm_debug.swj_dp.
|
6
|
-
$dut_jtag.arm_debug.swj_dp.
|
7
|
-
|
8
|
-
$dut_jtag.arm_debug.
|
9
|
-
|
11
|
+
# Some deprecated methods
|
12
|
+
$dut_jtag.arm_debug.swj_dp.read_expect_ap(0x01000004, edata: 0x10101010)
|
13
|
+
$dut_jtag.arm_debug.swj_dp.write_read_ap(0x01000004, 0x01010101)
|
14
|
+
$dut_jtag.arm_debug.swj_dp.write_read_ap(0x01000004, 0x10101010, edata: 0x10100000)
|
15
|
+
|
16
|
+
$dut_jtag.arm_debug.jtag.ir_value
|
10
17
|
end
|