origen_arm_debug 0.10.1 → 1.0.0.pre1

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.
data/config/users.rb DELETED
@@ -1,19 +0,0 @@
1
- # This file defines the users associated with your project, it is basically the
2
- # mailing list for release notes.
3
- #
4
- # You can split your users into "admin" and "user" groups, the main difference
5
- # between the two is that admin users will get all tag emails, users will get
6
- # emails on external/official releases only.
7
- #
8
- # Users are also prohibited from running the "origen tag" task, but this is
9
- # really just to prevent a casual user from executing it inadvertently and is
10
- # not intended to be a serious security gate.
11
- module Origen
12
- module Users
13
- def users
14
- @users ||= [
15
-
16
- ]
17
- end
18
- end
19
- end
@@ -1,113 +0,0 @@
1
- module OrigenARMDebug
2
- # To use this driver the owner model must include the SWD or JTAG protocol drivers:
3
- # include JTAG
4
- # or
5
- # include SWD
6
- #
7
- class Driver
8
- include Origen::Model
9
-
10
- # Returns the parent object that instantiated the driver, could be
11
- # either a DUT object or a protocol abstraction
12
- attr_reader :owner
13
-
14
- # Customizable delay that will be applied after any read/write register transaction
15
- # defaults to 0
16
- attr_reader :latency
17
-
18
- # Initialize class variables
19
- #
20
- # @param [Hash] options Options to customize the operation
21
- #
22
- # @example
23
- # DUT.new.arm_debug
24
- #
25
- def initialize(options = {})
26
- # 'buffer' register to bridge the actual memory-mapped register to the internal DAP transactions
27
- # (also used to support case on non-register based calls)
28
- add_reg :buffer, 0x00, 32, data: { pos: 0, bits: 32 }
29
-
30
- @latency = options[:latency] || 0
31
- instantiate_subblocks(options)
32
- end
33
-
34
- def instantiate_subblocks(options = {})
35
- sub_block :swj_dp, class_name: 'OrigenARMDebug::SWJ_DP'
36
-
37
- if options[:aps].nil?
38
- add_mem_ap('mem_ap', 0x00000000)
39
- else
40
- options[:aps].each do |key, value|
41
- add_mem_ap(key, value)
42
- end
43
- end
44
- end
45
-
46
- # Method to add additional Memory Access Ports (MEM-AP) with specified base address
47
- #
48
- # @param [Integer] name Short name for mem_ap that is being created
49
- # @param [Integer] base_address Base address
50
- #
51
- # @examples
52
- # arm_debug.add_mem_ap('alt_ahbapi', 0x02000000)
53
- #
54
- def add_mem_ap(name, base_address)
55
- domain name.to_sym
56
- sub_block name.to_sym, class_name: 'OrigenARMDebug::MemAP', base_address: base_address
57
- end
58
-
59
- # Create and/or return the SWJ_DP object with specified protocol
60
- # def swj_dp
61
- # if parent.respond_to?(:swd)
62
- # @swj_dp ||= SWJ_DP.new(self, :swd)
63
- # elsif parent.respond_to?(:jtag)
64
- # @swj_dp ||= SWJ_DP.new(self, :jtag)
65
- # end
66
- # end
67
- def abs_if
68
- swj_dp
69
- end
70
- alias_method :apapi, :abs_if
71
- alias_method :dpapi, :abs_if
72
-
73
- # Read from a MEM-AP register
74
- #
75
- # @param [Integer, Origen::Register::Reg, Origen::Register::BitCollection, Origen::Register::Bit] reg_or_val
76
- # Value to be read. If a reg/bit collection is supplied this can be pre-marked for
77
- # read, store or overlay and which will result in the requested action being applied to
78
- # the cycles corresponding to those bits only (don't care cycles will be generated for the others).
79
- # @param [Hash] options Options to customize the operation
80
- def read_register(reg_or_val, options = {})
81
- if options[:ap].nil?
82
- ap = mem_ap # default to 'mem_ap' if no AP is specified as an option
83
- else
84
- ap = eval(options[:ap].to_s)
85
- end
86
- ap.read_register(reg_or_val, options)
87
- end
88
-
89
- # Write data to a MEM-AP register
90
- #
91
- # @param [Integer, Origen::Register::Reg, Origen::Register::BitCollection, Origen::Register::Bit] reg_or_val
92
- # Value to be written to. If a reg/bit collection is supplied this can be pre-marked for
93
- # read, store or overlay and which will result in the requested action being applied to
94
- # the cycles corresponding to those bits only (don't care cycles will be generated for the others).
95
- # @param [Hash] options Options to customize the operation
96
- def write_register(reg_or_val, options = {})
97
- if options[:ap].nil?
98
- ap = mem_ap # default to 'mem_ap' if no AP is specified as an option
99
- else
100
- ap = eval(options[:ap].to_s)
101
- end
102
- ap.write_register(reg_or_val, options)
103
- end
104
-
105
- def jtag
106
- parent.jtag
107
- end
108
-
109
- def swd
110
- parent.swd
111
- end
112
- end
113
- end
@@ -1,19 +0,0 @@
1
- module OrigenARMDebug
2
- # Simple JTAG-specific dut model that inherits from protocol-agnostic DUT model
3
- class JTAG_DUT < DUT
4
- include OrigenJTAG
5
-
6
- # Adds jtag-required pins to the simple dut model
7
- # Returns nothing.
8
- def initialize
9
- super
10
- add_pin :tclk
11
- add_pin :tdi
12
- add_pin :tdo
13
- add_pin :tms
14
- add_pin :trst
15
- add_pin :swd_clk
16
- add_pin :swd_dio
17
- end
18
- end
19
- end
@@ -1,426 +0,0 @@
1
- module OrigenARMDebug
2
- # Object that defines API for performing Debug AP transations using SWD or JTAG
3
- class SWJ_DP
4
- include Origen::Model
5
-
6
- # Customizable delay for DUT-specific required cycles for write_ap transaction
7
- # to complete
8
- attr_accessor :write_ap_dly
9
-
10
- # Customizable delay for DUT-specific required cycles for acc_access transaction
11
- # to complete
12
- attr_accessor :acc_access_dly
13
-
14
- # Customizable random number generator mode.
15
- # compress: any uncompared data will be set to 0 when shifted out for better vector compression
16
- # unrolled: any uncompared data will be set to 5 when shifted out for complete unrolling of JTAG data
17
- # random: true random number generation, not ideal for pattern comparison
18
- attr_accessor :random_mode
19
-
20
- # Initialize class variables
21
- #
22
- # @param [Hash] options Options to customize the operation
23
- #
24
- # @example
25
- # # Create new SWD::Driver object
26
- # DUT.new.arm_debug.swj_dp
27
- #
28
- def initialize(options = {})
29
- @random_mode = :compress
30
- @write_ap_dly = 8
31
- @acc_access_dly = 7
32
- @current_apaddr = 0
33
- @orundetect = 0
34
-
35
- add_reg :ir, 0x00, 4, data: { pos: 0, bits: 4 } # ARM-JTAG Instruction Register
36
-
37
- add_reg :swd_dp, 0x00, 32, data: { pos: 0, bits: 32 } # SWD Register
38
-
39
- # jtag-dp only
40
- add_reg :dpacc, 0x00, 35, rnw: { pos: 0 }, # DP-Access Register (DPACC)
41
- a: { pos: 1, bits: 2 },
42
- data: { pos: 3, bits: 32 }
43
-
44
- add_reg :apacc, 0x00, 35, rnw: { pos: 0 }, # AP-Access Register (APACC)
45
- a: { pos: 1, bits: 2 },
46
- data: { pos: 3, bits: 32 }
47
-
48
- add_reg :idcode, 0x00, 32, data: { pos: 0, bits: 32 } # Device ID Code Register (IDCODE)
49
- add_reg :abort, 0x00, 35, rnw: { pos: 0 }, # Abort Register (ABORT)
50
- a: { pos: 1, bits: 2 },
51
- data: { pos: 3, bits: 32 }
52
-
53
- # DP Registers
54
- add_reg :dpidr, 0x00, 32, data: { pos: 0, bits: 32 }
55
- add_reg :ctrl_stat, 0x04, 32, data: { pos: 0, bits: 32 }
56
- add_reg :select, 0x08, 32, data: { pos: 0, bits: 32 }
57
- add_reg :rdbuff, 0x0C, 32, data: { pos: 0, bits: 32 }
58
- end
59
-
60
- #-------------------------------------
61
- # DPACC Access API
62
- #-------------------------------------
63
-
64
- # Method to read from a Debug Port register
65
- #
66
- # @param [String] name Name of register to be read from
67
- # Supports: :idcode,:abort,:ctrl_stat,:select,:rdbuff,:wcr,:resend
68
- # @param [Integer] data Value to be read
69
- # @param [Hash] options Options to customize the operation
70
- def read_dp(name, data, options = {})
71
- if protocol == :swd
72
- case name
73
- when :idcode, :ctrl_stat, :rdbuff, :wcr, :resend
74
- dpacc_access(name, 1, data, options)
75
- when :abort, :ctrl_stat
76
- log.error "#{name} #{protocol.to_s.upcase}-DP register is write-only!"
77
- else
78
- log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
79
- end
80
- else
81
- case name
82
- when :idcode
83
- set_ir(name)
84
- jtag.write_dr(random, size: 32)
85
- when :abort
86
- log.error "#{name} #{protocol.to_s.upcase}-DP register is write-only!"
87
- when :ctrl_stat, :select
88
- dpacc_access(name, 1, random, options)
89
- when :rdbuff
90
- dpacc_access(name, 1, data, options)
91
- else
92
- log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
93
- end
94
- read_dp(:rdbuff, data, options) if name != :idcode && name != :rdbuff
95
- end
96
- msg = "#{protocol.to_s.upcase}-DP: R-32: name='#{name.to_s.upcase}'"
97
- msg += ", expected=#{data.to_s(16).rjust(8, '0')}" # if name == :rdbuff
98
- cc msg
99
- end
100
-
101
- # Method to write to a Debug Port register
102
- #
103
- # @param [String] name Name of register to be written to
104
- # Supports: :idcode,:abort,:ctrl_stat,:select,:rdbuff,:wcr,:resend
105
- # @param [Integer] data Value to written
106
- # @param [Hash] options Options to customize the operation
107
- def write_dp(name, data, options = {})
108
- if protocol == :swd
109
- case name
110
- when :idcode, :rdbuff, :resend
111
- log.error "#{name} #{protocol.to_s.upcase}-DP register is read-only!"
112
- when :abort, :ctrl_stat, :select, :wcr
113
- dpacc_access(name, 0, data, options)
114
- else
115
- log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
116
- end
117
- else
118
- case name
119
- when :idcode, :rdbuff
120
- log.error "#{name} #{protocol.to_s.upcase}-DP register is read-only!"
121
- when :abort, :ctrl_stat, :select
122
- dpacc_access(name, 0, data, options)
123
- else
124
- log.error "Unknown #{protocol.to_s.upcase}-DP register name #{name}"
125
- end
126
- end
127
- cc "#{protocol.to_s.upcase}-DP: W-32: name='#{name.to_s.upcase}', data=0x#{data.to_s(16).rjust(8, '0')}"
128
- end
129
-
130
- # Method to write to and then read from a Debug Port register
131
- #
132
- # @param [String] name Name of register to be written to and read from
133
- # Supports: :idcode,:abort,:ctrl_stat,:select,:rdbuff,:wcr,:resend
134
- # @param [Integer] data Value to written
135
- # @param [Hash] options Options to customize the operation
136
- def write_read_dp(name, data, options = {})
137
- write_dp(name, data, options)
138
- if options[:actual].nil?
139
- read_dp(name, data, options)
140
- else
141
- rdata = options.delete(:actual)
142
- read_dp(name, rdata, options)
143
- end
144
-
145
- cc "#{protocol.to_s.upcase}-DP: WR-32: name='#{name.to_s.upcase}', data=0x#{data.to_s(16).rjust(8, '0')}"
146
- end
147
-
148
- #-------------------------------------
149
- # APACC Access API
150
- #-------------------------------------
151
-
152
- # Method to read from a Access Port register
153
- #
154
- # @param [Integer] addr Address of register to be read from
155
- # @param [Hash] options Options to customize the operation
156
- # @option options [Integer] edata Value to compare read data against
157
- def read_ap(addr, data, options = {})
158
- rwb = 1
159
- # Create another copy of options with select keys removed.
160
- # This first read is junk so we do not want to store it or compare it.
161
- junk_options = options.clone.delete_if do |key, val|
162
- (key.eql?(:r_mask) && val.eql?('store')) || key.eql?(:compare_data) || key.eql?(:reg)
163
- end
164
- junk_options[:mask] = 0x00000000
165
- apacc_access(addr, rwb, random, junk_options)
166
- read_dp(:rdbuff, data, options) # This is the real data
167
- cc "#{protocol.to_s.upcase}-AP: R-32: addr=0x#{addr.to_s(16).rjust(8, '0')}"
168
- end
169
-
170
- # Method to read from a Access Port register and compare against specific value
171
- #
172
- # @param [Integer] addr Address of register to be read from
173
- # @param [Integer] edata Value to compare read data against
174
- # @param [Hash] options Options to customize the operation
175
- def read_expect_ap(addr, options = {})
176
- # Warn caller that this method is being deprecated
177
- msg = 'Use swj_dp.read_ap(addr, data, options) instead of read_expect_ap(addr, edata: 0xXXXXXXX)'
178
- Origen.deprecate msg
179
-
180
- edata = options[:edata] || 0x00000000
181
- read_ap(addr, edata, options)
182
- end
183
- alias_method :wait_read_expect_ap, :read_expect_ap
184
-
185
- # Method to write to a Access Port register
186
- #
187
- # @param [Integer] addr Address of register to be read from
188
- # @param [Integer] data Value to written
189
- # @param [Hash] options Options to customize the operation
190
- def write_ap(addr, data, options = {})
191
- rwb = 0
192
- options[:mask] = 0x00000000
193
- # options = { w_attempts: 1 }.merge(options)
194
- apacc_access(addr, rwb, data, options)
195
- $tester.cycle(repeat: @write_ap_dly) if protocol == :jtag
196
- cc "#{protocol.to_s.upcase}-AP: W-32: "\
197
- "addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
198
- "data=0x#{data.to_s(16).rjust(8, '0')}"
199
- end
200
-
201
- # Method to write to and then read from a Debug Port register
202
- #
203
- # @param [Integer] addr Address of register to be read from
204
- # @param [Integer] data Value to written
205
- # @param [Hash] options Options to customize the operation
206
- def write_read_ap(addr, data, options = {})
207
- # Warn caller that this method is being deprecated
208
- msg = 'Use write_ap(addr, data, options); read_ap(addr, data, options) instead of write_read_ap'
209
- Origen.deprecate msg
210
-
211
- write_ap(addr, data, options)
212
- if options[:edata].nil?
213
- read_ap(addr, data, options)
214
- else
215
- read_ap(addr, options[:edata], options)
216
- end
217
-
218
- cc "#{protocol.to_s.upcase}: WR-32: "\
219
- "addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
220
- "data=0x#{data.to_s(16).rjust(8, '0')}"
221
- end
222
-
223
- private
224
-
225
- #-----------------------------------------------
226
- # DPACC Access Implementation-Specific methods
227
- #-----------------------------------------------
228
-
229
- # Method
230
- #
231
- # @param [Integer] name Name of register to be transacted
232
- # @param [Integer] rwb Indicates read or write
233
- # @param [Integer] data Value of data to be written
234
- # @param [Hash] options Options to customize the operation
235
- def dpacc_access(name, rwb, data, options = {})
236
- addr = get_dp_addr(name)
237
- if name == :ctrl_stat && protocol == :swd
238
- set_apselect(@current_apaddr & 0xFFFFFFFE, options)
239
- end
240
- set_ir(name) if protocol == :jtag
241
- options = { name: name }.merge(options)
242
- acc_access(addr, rwb, 0, data, options)
243
- end
244
-
245
- # Method
246
- #
247
- # @param [Integer] addr Address of register to be transacted
248
- # @param [Integer] rwb Indicates read or write
249
- # @param [Integer] data Value of data to be written
250
- # @param [Hash] options Options to customize the operation
251
- def apacc_access(addr, rwb, data, options = {})
252
- set_apselect((addr & 0xFFFFFFFE) | (@current_apaddr & 1), options)
253
- if protocol == :swd
254
- options.delete(:w_delay) if options.key?(:w_delay)
255
- else
256
- set_ir(:apacc)
257
- end
258
- options = { name: :apacc }.merge(options)
259
- acc_access((addr & 0xC), rwb, 1, data, options)
260
- end
261
-
262
- # Method
263
- #
264
- # @param [Integer] addr Address of register to be transacted
265
- # @param [Integer] rwb Indicates read or write
266
- # @param [Integer] ap_dp Indicates Access Port or Debug Port
267
- # @param [Integer] data Value of data to be written
268
- # @param [Hash] options Options to customize the operation
269
- def acc_access(addr, rwb, ap_dp, data, options = {})
270
- if protocol == :swd
271
- acc_access_swd(addr, rwb, ap_dp, data, options)
272
- else
273
- acc_access_jtag(addr, rwb, ap_dp, data, options)
274
- end
275
- end
276
-
277
- # Method SWD-specific
278
- #
279
- # @param [Integer] addr Address of register to be transacted
280
- # @param [Integer] rwb Indicates read or write
281
- # @param [Integer] ap_dp Indicates Access Port or Debug Port
282
- # @param [Integer] data Value of data to be written
283
- # @param [Hash] options Options to customize the operation
284
- def acc_access_swd(addr, rwb, ap_dp, data, options = {})
285
- _name = options.delete(:name)
286
- if (rwb == 1)
287
- reg(:swd_dp).address = addr
288
- reg(:swd_dp).bits(:data).clear_flags
289
- reg(:swd_dp).bits(:data).write(data)
290
- _mask = options[:mask] || 0xFFFFFFFF
291
- _store = options[:store] || 0x00000000
292
- 0.upto(31) do |i|
293
- reg(:swd_dp).bits(:data)[i].read if _mask[i] == 1
294
- reg(:swd_dp).bits(:data)[i].store if _store[i] == 1
295
- end
296
- options = options.merge(size: reg(:swd_dp).size)
297
- swd.read(ap_dp, reg(:swd_dp), options)
298
- else
299
- reg(:swd_dp).bits(:data).write(data)
300
- reg(:dpacc).address = addr
301
- options = options.merge(size: reg(:swd_dp).size)
302
- swd.write(ap_dp, reg(:swd_dp), reg(:swd_dp).data, options)
303
- end
304
- options = { w_delay: 10 }.merge(options)
305
- swd.swd_dio_to_0(options[:w_delay])
306
- end
307
-
308
- # Method JTAG-specific
309
- #
310
- # @param [Integer] addr Address of register to be transacted
311
- # @param [Integer] rwb Indicates read or write
312
- # @param [Integer] ap_dp Indicates Access Port or Debug Port
313
- # @param [Integer] data Value of data to be written
314
- # @param [Hash] options Options to customize the operation
315
- def acc_access_jtag(addr, rwb, ap_dp, data, options = {})
316
- _name = options.delete(:name)
317
- attempts = options[:attempts] || 1
318
- attempts.times do
319
- if _name == :rdbuff
320
- reg(:dpacc).bits(:data).clear_flags
321
- reg(:dpacc).bits(:data).write(data)
322
- _mask = options[:mask] || 0xFFFFFFFF
323
- _store = options[:store] || 0x00000000
324
- 0.upto(31) do |i|
325
- reg(:dpacc).bits(:data)[i].read if _mask[i] == 1
326
- reg(:dpacc).bits(:data)[i].store if _store[i] == 1
327
- end
328
- options = options.merge(size: reg(:dpacc).size)
329
- jtag.read_dr(reg(:dpacc), options)
330
- else
331
- reg(:dpacc).bits(:data).write(data)
332
- reg(:dpacc).bits(:a).write((addr & 0x0000000C) >> 2)
333
- reg(:dpacc).bits(:rnw).write(rwb)
334
- options = options.merge(size: reg(:dpacc).size)
335
- jtag.write_dr(reg(:dpacc), options)
336
- end
337
- end
338
- $tester.cycle(repeat: @acc_access_dly)
339
- end
340
-
341
- # Returns the address of the register based on the name (string) of the register
342
- #
343
- # @param [String] name Name of the register
344
- def get_dp_addr(name)
345
- case name
346
- when :idcode then return 0x0
347
- when :abort then return 0x0
348
- when :ctrl_stat then return 0x4
349
- when :select then return 0x8
350
- when :rdbuff then return 0xC
351
- when :wcr then return 0x4
352
- when :resend then return 0x8
353
- end
354
- end
355
-
356
- # Shifts IR code into the JTAG/ARM Instruction Regsiter based on requested Register Name
357
- #
358
- # @param [String] name Name of the register to be interacted with
359
- def set_ir(name)
360
- case name
361
- when :idcode
362
- reg(:ir).write(0b1110) # JTAGC_ARM_IDCODE
363
- when :abort
364
- reg(:ir).write(0b1000) # JTAGC_ARM_ABORT
365
- when :ctrl_stat, :select, :rdbuff
366
- reg(:ir).write(0b1010) # JTAGC_ARM_DPACC
367
- when :apacc
368
- reg(:ir).write(0b1011) # JTAGC_ARM_APACC
369
- end
370
- jtag.write_ir(reg(:ir), size: reg(:ir).size)
371
- end
372
-
373
- # Method to select an Access Port (AP) by writing to the SELECT register in the Debug Port
374
- #
375
- # @param [Integer] addr Address to be written to the SELECT register. It's value
376
- # will determine which Access Port is selected.
377
- # @param [Hash] options Options to customize the operation
378
- def set_apselect(addr, options = {})
379
- if protocol == :swd
380
- addr &= 0xff0000f1
381
- else
382
- addr &= 0xff0000f0
383
- end
384
-
385
- if (addr != @current_apaddr)
386
- write_dp(:select, addr & 0xff0000ff, options)
387
- end
388
- @current_apaddr = addr
389
- end
390
-
391
- # Generates 32-bit number for 'dont care' jtag shift outs. Value generated
392
- # depends on class variable 'random_mode'.
393
- def random
394
- case @random_mode
395
- when :compress then return 0x00000000
396
- when :unrolled then return 0x55555555
397
- when :random then return rand(4_294_967_295)
398
- else return 0x00000000
399
- end
400
- end
401
-
402
- # Provides shortname access to top-level jtag driver
403
- def jtag
404
- parent.parent.jtag
405
- end
406
-
407
- # Provides shortname access to top-level swd driver
408
- def swd
409
- parent.parent.swd
410
- end
411
-
412
- # Returns protocol implemented at the top-level (i.e. SWD or JTAG)
413
- def protocol
414
- if parent.parent.respond_to?(:swd)
415
- implementation = :swd
416
- elsif parent.parent.respond_to?(:jtag)
417
- implementation = :jtag
418
- end
419
- implementation
420
- end
421
-
422
- def log
423
- Origen.log
424
- end
425
- end
426
- end