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.
- checksums.yaml +4 -4
- data/config/application.rb +3 -3
- data/config/boot.rb +5 -0
- data/config/commands.rb +14 -9
- data/config/version.rb +4 -4
- data/lib/origen_arm_debug.rb +7 -11
- data/lib/origen_arm_debug/ap.rb +14 -0
- data/lib/origen_arm_debug/ap_controller.rb +27 -0
- data/lib/origen_arm_debug/dap.rb +89 -0
- data/lib/origen_arm_debug/dap_controller.rb +14 -0
- data/lib/origen_arm_debug/dp_controller.rb +17 -0
- data/lib/origen_arm_debug/helpers.rb +28 -0
- data/lib/origen_arm_debug/jtag_ap.rb +10 -0
- data/lib/origen_arm_debug/jtag_ap_controller.rb +6 -0
- data/lib/origen_arm_debug/jtag_dp.rb +59 -0
- data/lib/origen_arm_debug/jtag_dp_controller.rb +140 -0
- data/lib/origen_arm_debug/mem_ap.rb +33 -283
- data/lib/origen_arm_debug/mem_ap_controller.rb +81 -0
- data/lib/origen_arm_debug/sw_dp.rb +65 -0
- data/lib/origen_arm_debug/sw_dp_controller.rb +47 -0
- data/lib/{origen_arm_debug → origen_arm_debug_dev}/dut.rb +11 -15
- data/lib/origen_arm_debug_dev/dut_jtag.rb +32 -0
- data/lib/{origen_arm_debug → origen_arm_debug_dev}/dut_swd.rb +7 -1
- data/pattern/workout.rb +61 -0
- data/templates/web/index.md.erb +16 -4
- metadata +38 -48
- data/config/development.rb +0 -17
- data/config/environment.rb +0 -3
- data/config/users.rb +0 -19
- data/lib/origen_arm_debug/driver.rb +0 -113
- data/lib/origen_arm_debug/dut_jtag.rb +0 -19
- data/lib/origen_arm_debug/swj_dp.rb +0 -426
- data/pattern/read_write_reg.rb +0 -33
- data/pattern/read_write_reg_jtag.rb +0 -17
- data/pattern/read_write_reg_swd.rb +0 -22
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
|