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.
@@ -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
- # ARM Debug Interface v5.1
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(owner, options = {})
30
- @owner = owner
31
- @name = options[:name].nil? ? 'default' : options[:name]
32
- @base_address = options[:base_address].nil? ? 0x00000000 : options[:base_address]
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
- # reset values for MEM-AP registers
35
- @current_csw = 0x00000000
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
- owner.swj_dp
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 read_register(reg_or_val, options = {})
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
- rdata = reg_or_val.data
72
- options = { reg: reg_or_val }.merge(options)
48
+ data = reg_or_val.data
73
49
  else
74
- addr = reg_or_val # if not a register, use the 'val' as target addr
75
- rdata = 0
50
+ addr = options[:address]
51
+ data = reg_or_val
76
52
  end
53
+ size = options[:size] || 32
77
54
 
78
- options = { size: 32 }.merge(options)
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
- debug_port.read_ap(drw_reg_addr, options)
87
- rdata = get_rdata(size, addr, rdata)
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}): R-#{size.to_s(10)}: "\
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 write_register(reg_or_val, options = {});
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
- wdata = reg_or_val.data
98
- options = { reg: reg_or_val }.merge(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 = reg_or_val # if not a register, use the 'val' as target addr
101
- wdata = options[:wdata]
76
+ addr = options[:address]
77
+ data = reg_or_val
102
78
  end
103
- options = { size: 32 }.merge(options)
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
- wdata = get_wdata(size, addr, wdata)
112
- debug_port.write_ap(drw_reg_addr, wdata, options)
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}): WR-#{size.to_s(10)}: "\
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
- # Method to read from a mem_ap register
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
- options = { size: 32 }.merge(options)
138
- options = { r_mask: 'mask', r_attempts: 1 }.merge(options)
139
- msg = 'Arm Debug: Shift out data for reading'
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
- cc "MEM-AP(#{@name}): R-#{size.to_s(10)}: "\
150
- "addr=0x#{addr.to_s(16).rjust(size / 4, '0')}"
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
- options = { size: 32 }.merge(options)
165
- options = { w_attempts: 1 }.merge(options)
166
- msg = "Arm Debug: Shift in data to write: #{wdata.to_hex}"
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
- cc "MEM-AP(#{@name}): WR-#{size.to_s(10)}: "\
177
- "addr=0x#{addr.to_s(16).rjust(size / 4, '0')}, "\
178
- "data=0x#{wdata.to_s(16).rjust(size / 4, '0')}"
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 (legacy)
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.read(addr, options) instead of R(addr, rdata, options)'
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
- # Patch arguments and send to new method
234
- options = { rdata: rdata }.merge(options)
235
- read(addr, options)
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 = 0x00000000
284
- when 16 then new_size = 0x00000001
285
- when 32 then new_size = 0x00000002
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 (@current_csw == 0x00000000)
290
- debug_port.read_ap(csw_reg_addr)
291
- @current_csw = 0x23000040
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
- csw_size = @current_csw & 0x00000003
295
- if (csw_size != new_size)
296
- new_csw = (@current_csw & 0xfffffffc) | new_size
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 (@current_tar != addr)
310
- debug_port.write_ap(tar_reg_addr, addr, options)
217
+ if (reg(:tar).data != addr)
218
+ debug_port.write_ap(reg(:tar).address, addr, options)
311
219
  end
312
- @current_tar = addr;
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
- current_csw_5_4 = (@current_csw & 0x00000030) >> 4
318
- current_csw_2_0 = @current_csw & 0x00000007
319
- if (current_csw_5_4 == 0b01)
320
- case current_csw_2_0
321
- when 0 then @current_tar += 1 # Increment single
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 (current_csw_5_4 == 2)
326
- @current_tar += 4 # Increment packed
231
+ elsif reg(:csw).bits(:addr_inc).data == 2
232
+ reg(:tar).data += 4 # Increment packed
327
233
  end
328
234
 
329
- if current_csw_5_4 && ((@current_tar & 0xfffffc00) == 0xffffffff)
235
+ if reg(:csw).bits(:addr_inc) && ((reg(:tar).data & 0xfffffc00) == 0xffffffff)
330
236
  # reset tar when attempting to increment past 1kB boundary
331
- @current_tar = 0xffffffff
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