origen_arm_debug 0.10.1 → 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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