origen_arm_debug 1.2.0 → 1.3.1
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/boot.rb +1 -0
- data/config/commands.rb +4 -0
- data/config/version.rb +2 -2
- data/lib/origen_arm_debug/dap.rb +5 -1
- data/lib/origen_arm_debug/dp_controller_v6.rb +17 -0
- data/lib/origen_arm_debug/jtag_dp.rb +9 -1
- data/lib/origen_arm_debug/jtag_dp_controller.rb +15 -3
- data/lib/origen_arm_debug/jtag_dp_v6.rb +94 -0
- data/lib/origen_arm_debug/jtag_dp_v6_controller.rb +179 -0
- data/lib/origen_arm_debug.rb +3 -0
- data/lib/origen_arm_debug_dev/dut_jtag_axi.rb +15 -0
- data/lib/origen_arm_debug_dev/dut_jtag_axi_ack.rb +51 -0
- data/pattern/v6_workout.rb +118 -0
- data/pattern/workout.rb +5 -1
- data/templates/web/index.md.erb +30 -0
- metadata +10 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90de517c3d56ac340822b45422164150dc6b5639a9a068608cc8679858eb09bd
|
|
4
|
+
data.tar.gz: 1d8c7b2e21b429a4e90f05813689a743cb00a69caad43c207a46499bcc40414a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 906a61042cc140e79a32c2cd82509b9b001efc84cf5eaf6e63b6570740247d56550b8fce74532ffef6c4dc111dba2c2fdfca1487808f7aecbd9efa5e37f9ab86
|
|
7
|
+
data.tar.gz: e8ccad6598ea0da7da0d745d76fe1939df44add8bb002d40e38f8733a5329269818d3433768f67e9293ceb5a92522cc17634542d024bacaa0435692b121db7e5
|
data/config/boot.rb
CHANGED
data/config/commands.rb
CHANGED
|
@@ -30,6 +30,10 @@ when "examples", "test"
|
|
|
30
30
|
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
|
31
31
|
ARGV = %w(workout -t jtag_axi.rb -e j750 -r approved)
|
|
32
32
|
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
|
33
|
+
ARGV = %w(v6_workout -t jtag_axi.rb -e j750 -r approved)
|
|
34
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
|
35
|
+
ARGV = %w(v6_workout -t jtag_ack.rb -e j750 -r approved)
|
|
36
|
+
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
|
33
37
|
ARGV = %w(workout -t swd -e j750 -r approved)
|
|
34
38
|
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
|
35
39
|
ARGV = %w(workout -t dual_dp -e j750 -r approved)
|
data/config/version.rb
CHANGED
data/lib/origen_arm_debug/dap.rb
CHANGED
|
@@ -20,7 +20,11 @@ module OrigenARMDebug
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
if options[:jtag] || parent.respond_to?(:jtag)
|
|
23
|
-
options[:
|
|
23
|
+
if options[:dapv6]
|
|
24
|
+
options[:class_name] = 'JTAG_DPV6'
|
|
25
|
+
else
|
|
26
|
+
options[:class_name] = 'JTAG_DP'
|
|
27
|
+
end
|
|
24
28
|
dps << sub_block(:jtag_dp, options)
|
|
25
29
|
end
|
|
26
30
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module OrigenARMDebug
|
|
2
|
+
# Common methods shared between the SW and JTAG DP controllers
|
|
3
|
+
module DPControllerV6
|
|
4
|
+
# Alias for the ctrlstat register
|
|
5
|
+
def ctrl_stat
|
|
6
|
+
ctrlstat
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# @api private
|
|
10
|
+
def select_ap_reg(reg)
|
|
11
|
+
address = (reg.address & 0xFFFF_FFF0) >> 4
|
|
12
|
+
address1 = (reg.address & 0xFFFF_FFFF_0000_0000) >> 32
|
|
13
|
+
model.select1.write! address1 if model.select1.data != address1
|
|
14
|
+
model.select.bits(:addr).write! address if model.select.bits(:addr).data != address
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -2,7 +2,7 @@ module OrigenARMDebug
|
|
|
2
2
|
class JTAG_DP
|
|
3
3
|
include Origen::Model
|
|
4
4
|
|
|
5
|
-
attr_reader :dpacc_select, :apacc_select
|
|
5
|
+
attr_reader :dpacc_select, :apacc_select, :read_ack
|
|
6
6
|
|
|
7
7
|
def initialize(options = {})
|
|
8
8
|
options = {
|
|
@@ -14,6 +14,14 @@ module OrigenARMDebug
|
|
|
14
14
|
}.merge(options)
|
|
15
15
|
@dpacc_select = options[:dpacc_select]
|
|
16
16
|
@apacc_select = options[:apacc_select]
|
|
17
|
+
# the acknowledge signature is LHL (2), but allow an override
|
|
18
|
+
if options[:read_ack]
|
|
19
|
+
if options[:read_ack] == true
|
|
20
|
+
@read_ack = 2
|
|
21
|
+
else
|
|
22
|
+
@read_ack = options[:read_ack]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
17
25
|
add_reg :ir, 0, size: options[:ir_size]
|
|
18
26
|
|
|
19
27
|
# Virtual reg used to represent all of the various 35-bit scan chains
|
|
@@ -92,6 +92,7 @@ module OrigenARMDebug
|
|
|
92
92
|
# Part 2 - Now read real data from RDBUFF (DP-Reg)
|
|
93
93
|
dr.reset
|
|
94
94
|
dr.overlay(nil)
|
|
95
|
+
# Should compare of ack be added here as well?
|
|
95
96
|
dr[0].write(1)
|
|
96
97
|
dr[2..1].write(rdbuff.offset >> 2)
|
|
97
98
|
dr[34..3].copy_all(reg)
|
|
@@ -129,10 +130,21 @@ module OrigenARMDebug
|
|
|
129
130
|
# Part 2 - Now read real data from RDBUFF (DP-Reg)
|
|
130
131
|
dr.reset
|
|
131
132
|
dr.overlay(nil)
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
|
|
134
|
+
read_ack = options[:read_ack] || model.read_ack
|
|
135
|
+
if read_ack
|
|
136
|
+
# Add in check of acknowledge bits (confirms the operation completed)
|
|
137
|
+
dr[2..0].read read_ack
|
|
138
|
+
else
|
|
139
|
+
# Default previous behavior is to mask, no way to know if the operation successfully completed
|
|
140
|
+
dr[0].write(1)
|
|
141
|
+
dr[2..1].write(rdbuff.offset >> 2)
|
|
142
|
+
end
|
|
134
143
|
dr[34..3].copy_all(reg)
|
|
135
|
-
|
|
144
|
+
unless options[:mask].nil?
|
|
145
|
+
options[:mask] = options[:mask] << 3
|
|
146
|
+
options[:mask] += 7 if read_ack
|
|
147
|
+
end
|
|
136
148
|
ir.write!(dpacc_select)
|
|
137
149
|
dut.jtag.read_dr(dr, options)
|
|
138
150
|
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module OrigenARMDebug
|
|
2
|
+
class JTAG_DPV6
|
|
3
|
+
include Origen::Model
|
|
4
|
+
|
|
5
|
+
attr_reader :dpacc_select, :apacc_select, :read_ack
|
|
6
|
+
|
|
7
|
+
def initialize(options = {})
|
|
8
|
+
options = {
|
|
9
|
+
ir_size: 4,
|
|
10
|
+
idcode_select: 0b1110,
|
|
11
|
+
abort_select: 0b1000,
|
|
12
|
+
dpacc_select: 0b1010,
|
|
13
|
+
apacc_select: 0b1011
|
|
14
|
+
}.merge(options)
|
|
15
|
+
@dpacc_select = options[:dpacc_select]
|
|
16
|
+
@apacc_select = options[:apacc_select]
|
|
17
|
+
# the acknowledge signature is HLL (4), but allow an override
|
|
18
|
+
if options[:read_ack]
|
|
19
|
+
if options[:read_ack] == true
|
|
20
|
+
@read_ack = 4
|
|
21
|
+
else
|
|
22
|
+
@read_ack = options[:read_ack]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
add_reg :ir, 0, size: options[:ir_size]
|
|
26
|
+
|
|
27
|
+
# Virtual reg used to represent all of the various 35-bit scan chains
|
|
28
|
+
reg :dr, 0, size: 35 do |reg|
|
|
29
|
+
reg.bit 34..3, :data
|
|
30
|
+
reg.bit 2..1, :a
|
|
31
|
+
reg.bit 0, :rnw
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
reg :idcode, options[:idcode_select], access: :ro do |reg|
|
|
35
|
+
reg.bit 31..28, :version
|
|
36
|
+
reg.bit 27..12, :partno
|
|
37
|
+
reg.bit 11..1, :designer
|
|
38
|
+
reg.bit 0, :bit0, reset: 1
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
reg :ctrlstat, 0x4, dpbanksel: 0 do |reg|
|
|
42
|
+
reg.bit 31, :csyspwrupack
|
|
43
|
+
reg.bit 30, :csyspwrupreq
|
|
44
|
+
reg.bit 29, :cdbgpwrupack
|
|
45
|
+
reg.bit 28, :cdbgpwrupreq
|
|
46
|
+
reg.bit 27, :cdbgrstack
|
|
47
|
+
reg.bit 26, :cdbgrstreq
|
|
48
|
+
reg.bit 23..12, :trncnt
|
|
49
|
+
reg.bit 11..8, :masklane
|
|
50
|
+
reg.bit 7, :wdataerr
|
|
51
|
+
reg.bit 6, :readok
|
|
52
|
+
reg.bit 5, :stickyerr
|
|
53
|
+
reg.bit 4, :stickycmp
|
|
54
|
+
reg.bit 3..2, :trnmode
|
|
55
|
+
reg.bit 1, :stickyorun
|
|
56
|
+
reg.bit 0, :orundetect
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
reg :select, 0x8 do |reg|
|
|
60
|
+
reg.bit 31..4, :addr
|
|
61
|
+
reg.bit 3..0, :dpbanksel
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
reg :select1, 0x4, dpbanksel: 5 do |reg|
|
|
65
|
+
reg.bit 31..0, :addr
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
select.write options[:dp_select_reset] if options[:dp_select_reset]
|
|
69
|
+
|
|
70
|
+
add_reg :rdbuff, 0xC, access: :ro, reset: 0
|
|
71
|
+
|
|
72
|
+
reg :abort, options[:abort_select], access: :wo do |reg|
|
|
73
|
+
reg.bit 0, :dapabort
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def select
|
|
78
|
+
reg(:select)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def abort
|
|
82
|
+
reg(:abort)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def is_jtag?
|
|
86
|
+
true
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def is_swd?
|
|
90
|
+
false
|
|
91
|
+
end
|
|
92
|
+
alias_method :is_sw?, :is_swd?
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
module OrigenARMDebug
|
|
2
|
+
class JTAG_DPV6Controller
|
|
3
|
+
include Origen::Controller
|
|
4
|
+
include Helpers
|
|
5
|
+
include DPControllerV6
|
|
6
|
+
|
|
7
|
+
def write_register(reg, options = {})
|
|
8
|
+
unless reg.writable?
|
|
9
|
+
fail "The :#{reg.name} register is not writeable!"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# DP register write
|
|
13
|
+
if reg.owner == model
|
|
14
|
+
# Don't log this one, not really a DP reg and will be included
|
|
15
|
+
# in the JTAG driver log anyway
|
|
16
|
+
if reg.name == :ir
|
|
17
|
+
dut.jtag.write_ir(reg)
|
|
18
|
+
else
|
|
19
|
+
|
|
20
|
+
log "Write JTAG-DP register #{reg.name.to_s.upcase}: #{reg.data.to_hex}" do
|
|
21
|
+
if reg.name == :abort
|
|
22
|
+
ir.write!(reg.offset)
|
|
23
|
+
dr.reset
|
|
24
|
+
dr.overlay(nil)
|
|
25
|
+
dr[2..0].write(0)
|
|
26
|
+
dr[34..3].copy_all(reg)
|
|
27
|
+
dut.jtag.write_dr(dr)
|
|
28
|
+
|
|
29
|
+
# DPACC
|
|
30
|
+
elsif reg.name == :select
|
|
31
|
+
dp_write(reg)
|
|
32
|
+
|
|
33
|
+
# Some other debug register
|
|
34
|
+
elsif reg.meta.include?(:dpbanksel)
|
|
35
|
+
if model.reg(:select).bits(:dpbanksel).data != reg.meta[:dpbanksel]
|
|
36
|
+
model.reg(:select).bits(:dpbanksel).write! reg.meta[:dpbanksel]
|
|
37
|
+
end
|
|
38
|
+
dp_write(reg)
|
|
39
|
+
|
|
40
|
+
else
|
|
41
|
+
fail "Can't write #{reg.name}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# AP register write
|
|
47
|
+
else
|
|
48
|
+
|
|
49
|
+
unless reg.owner.is_a?(AP)
|
|
50
|
+
fail 'The JTAG-DP can only write to DP or AP registers!'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
select_ap_reg(reg)
|
|
54
|
+
dr.reset
|
|
55
|
+
dr.overlay(nil)
|
|
56
|
+
dr[0].write(0)
|
|
57
|
+
dr[2..1].write(reg.offset >> 2)
|
|
58
|
+
dr[34..3].copy_all(reg)
|
|
59
|
+
ir.write!(apacc_select)
|
|
60
|
+
dut.jtag.write_dr(dr, options)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def read_register(reg, options = {})
|
|
65
|
+
unless reg.readable?
|
|
66
|
+
fail "The :#{reg.name} register is not readable!"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
if reg.owner == model
|
|
70
|
+
# Don't log this one, not really a DP reg and will be included
|
|
71
|
+
# in the JTAG driver log anyway
|
|
72
|
+
if reg.name == :ir
|
|
73
|
+
dut.jtag.read_ir(reg)
|
|
74
|
+
else
|
|
75
|
+
|
|
76
|
+
log "Read JTAG-DP register #{reg.name.to_s.upcase}: #{Origen::Utility.read_hex(reg)}" do
|
|
77
|
+
if reg.name == :idcode
|
|
78
|
+
ir.write!(reg.offset)
|
|
79
|
+
dut.jtag.read_dr(reg)
|
|
80
|
+
|
|
81
|
+
# DPACC
|
|
82
|
+
elsif reg.name == :select || reg.name == :rdbuff
|
|
83
|
+
dp_read(reg, options)
|
|
84
|
+
|
|
85
|
+
# Some other register
|
|
86
|
+
elsif reg.meta.include?(:dpbanksel)
|
|
87
|
+
# Part 1 - Set dpbanksel if required
|
|
88
|
+
if model.reg(:select).bits(:dpbanksel).data != reg.meta[:dpbanksel]
|
|
89
|
+
model.reg(:select).bits(:dpbanksel).write! reg.meta[:dpbanksel]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
dp_read(reg, options)
|
|
93
|
+
|
|
94
|
+
else
|
|
95
|
+
fail "Can't read #{reg.name}"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# AP register read
|
|
101
|
+
else
|
|
102
|
+
unless reg.owner.is_a?(AP)
|
|
103
|
+
fail 'The JTAG-DP can only write to DP or AP registers!'
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Part 1 - Request read from AP-Register by writing to APACC with RnW=1
|
|
107
|
+
select_ap_reg(reg)
|
|
108
|
+
dr.reset
|
|
109
|
+
dr.overlay(nil)
|
|
110
|
+
dr[0].write(1)
|
|
111
|
+
dr[2..1].write(reg.offset >> 2)
|
|
112
|
+
dr[34..3].write(0)
|
|
113
|
+
ir.write!(apacc_select)
|
|
114
|
+
dut.jtag.write_dr(dr)
|
|
115
|
+
|
|
116
|
+
# Calling AP should provide any delay parameter for wait states between AP read request
|
|
117
|
+
# and when the data is available at the RDBUFF DP-Reg
|
|
118
|
+
if options[:apacc_wait_states]
|
|
119
|
+
options[:apacc_wait_states].cycles
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Part 2 - Now read real data from RDBUFF (DP-Reg)
|
|
123
|
+
dr.reset
|
|
124
|
+
dr.overlay(nil)
|
|
125
|
+
|
|
126
|
+
read_ack = options[:read_ack] || model.read_ack
|
|
127
|
+
if read_ack
|
|
128
|
+
# Add in check of acknowledge bits (confirms the operation completed)
|
|
129
|
+
dr[2..0].read read_ack
|
|
130
|
+
else
|
|
131
|
+
# Default previous behavior is to mask, no way to know if the operation successfully completed
|
|
132
|
+
dr[0].write(1)
|
|
133
|
+
dr[2..1].write(rdbuff.offset >> 2)
|
|
134
|
+
end
|
|
135
|
+
dr[34..3].copy_all(reg)
|
|
136
|
+
unless options[:mask].nil?
|
|
137
|
+
options[:mask] = options[:mask] << 3
|
|
138
|
+
options[:mask] += 7 if read_ack
|
|
139
|
+
end
|
|
140
|
+
ir.write!(dpacc_select)
|
|
141
|
+
dut.jtag.read_dr(dr, options)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def dp_read(reg, options = {})
|
|
146
|
+
# Part 1 - Request read from DP-Register by writing to DPACC with RnW=1
|
|
147
|
+
dr.reset
|
|
148
|
+
dr.overlay(nil)
|
|
149
|
+
dr[0].write(1)
|
|
150
|
+
dr[2..1].write(reg.offset >> 2)
|
|
151
|
+
dr[34..3].write(0)
|
|
152
|
+
ir.write!(dpacc_select)
|
|
153
|
+
dut.jtag.write_dr(dr)
|
|
154
|
+
|
|
155
|
+
# Part 2 - Now read real data from RDBUFF (DP-Reg)
|
|
156
|
+
dr.reset
|
|
157
|
+
dr.overlay(nil)
|
|
158
|
+
dr[0].write(1)
|
|
159
|
+
dr[2..1].write(rdbuff.offset >> 2)
|
|
160
|
+
dr[34..3].copy_all(reg)
|
|
161
|
+
options[:mask] = options[:mask] << 3 unless options[:mask].nil?
|
|
162
|
+
dut.jtag.read_dr(dr, options)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def dp_write(reg)
|
|
166
|
+
dr.reset
|
|
167
|
+
dr.overlay(nil)
|
|
168
|
+
dr[0].write(0)
|
|
169
|
+
dr[2..1].write(reg.offset >> 2)
|
|
170
|
+
dr[34..3].copy_all(reg)
|
|
171
|
+
ir.write!(dpacc_select)
|
|
172
|
+
dut.jtag.write_dr(dr)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def base_address
|
|
176
|
+
model.base_address
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
data/lib/origen_arm_debug.rb
CHANGED
|
@@ -8,8 +8,11 @@ module OrigenARMDebug
|
|
|
8
8
|
require 'origen_arm_debug/dap'
|
|
9
9
|
require 'origen_arm_debug/dap_controller'
|
|
10
10
|
require 'origen_arm_debug/dp_controller'
|
|
11
|
+
require 'origen_arm_debug/dp_controller_v6'
|
|
11
12
|
require 'origen_arm_debug/jtag_dp'
|
|
12
13
|
require 'origen_arm_debug/jtag_dp_controller'
|
|
14
|
+
require 'origen_arm_debug/jtag_dp_v6'
|
|
15
|
+
require 'origen_arm_debug/jtag_dp_v6_controller'
|
|
13
16
|
require 'origen_arm_debug/sw_dp'
|
|
14
17
|
require 'origen_arm_debug/sw_dp_controller'
|
|
15
18
|
require 'origen_arm_debug/ap'
|
|
@@ -30,6 +30,21 @@ module OrigenARMDebugDev
|
|
|
30
30
|
options[:dp_select_reset] = 0xC2_0D00
|
|
31
31
|
# Specify (customize) ARM Debug implementation details
|
|
32
32
|
sub_block :arm_debug, options
|
|
33
|
+
|
|
34
|
+
options[:dapv6] = true
|
|
35
|
+
options[:class_name] = 'OrigenARMDebug::DAP'
|
|
36
|
+
options[:mem_aps] = {
|
|
37
|
+
mem_ap: {
|
|
38
|
+
base_address: 0x00C2_0000,
|
|
39
|
+
latency: 16,
|
|
40
|
+
apreg_access_wait: 8,
|
|
41
|
+
apmem_access_wait: 8,
|
|
42
|
+
is_axi: true,
|
|
43
|
+
csw_reset: 0x1080_6002
|
|
44
|
+
},
|
|
45
|
+
mdm_ap: 0x00C3_0000
|
|
46
|
+
}
|
|
47
|
+
sub_block :arm_debugv6, options
|
|
33
48
|
end
|
|
34
49
|
end
|
|
35
50
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module OrigenARMDebugDev
|
|
2
|
+
# Simple JTAG-specific dut model that inherits from protocol-agnostic DUT model
|
|
3
|
+
class JTAG_AXI_ACK_DUT < DUT
|
|
4
|
+
include OrigenJTAG
|
|
5
|
+
|
|
6
|
+
# Adds jtag-required pins to the simple dut model
|
|
7
|
+
# Returns nothing.
|
|
8
|
+
def initialize(options = {})
|
|
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
|
+
|
|
18
|
+
options[:class_name] = 'OrigenARMDebug::DAP'
|
|
19
|
+
options[:mem_aps] = {
|
|
20
|
+
mem_ap: {
|
|
21
|
+
base_address: 0x00000000,
|
|
22
|
+
latency: 16,
|
|
23
|
+
apreg_access_wait: 8,
|
|
24
|
+
apmem_access_wait: 8,
|
|
25
|
+
is_axi: true,
|
|
26
|
+
csw_reset: 0x1080_6002
|
|
27
|
+
},
|
|
28
|
+
mdm_ap: 0x01000000
|
|
29
|
+
}
|
|
30
|
+
options[:dp_select_reset] = 0xC2_0D00
|
|
31
|
+
options[:read_ack] = true
|
|
32
|
+
# Specify (customize) ARM Debug implementation details
|
|
33
|
+
sub_block :arm_debug, options
|
|
34
|
+
|
|
35
|
+
options[:dapv6] = true
|
|
36
|
+
options[:class_name] = 'OrigenARMDebug::DAP'
|
|
37
|
+
options[:mem_aps] = {
|
|
38
|
+
mem_ap: {
|
|
39
|
+
base_address: 0x00C2_0000,
|
|
40
|
+
latency: 16,
|
|
41
|
+
apreg_access_wait: 8,
|
|
42
|
+
apmem_access_wait: 8,
|
|
43
|
+
is_axi: true,
|
|
44
|
+
csw_reset: 0x1080_6002
|
|
45
|
+
},
|
|
46
|
+
mdm_ap: 0x00C3_0000
|
|
47
|
+
}
|
|
48
|
+
sub_block :arm_debugv6, options
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
if Origen.app.target.name == 'jtag_axi'
|
|
2
|
+
pattern_name = "v6_workout_#{dut.arm_debugv6.dp.name}"
|
|
3
|
+
elsif Origen.app.target.name == 'jtag_ack'
|
|
4
|
+
pattern_name = "v6_workout_#{dut.arm_debugv6.dp.name}_w_ack"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
Pattern.create name: pattern_name do
|
|
8
|
+
|
|
9
|
+
ss "Tests of direct DP API"
|
|
10
|
+
dp = dut.arm_debugv6.dp
|
|
11
|
+
|
|
12
|
+
dp.idcode.partno.read!(0x12)
|
|
13
|
+
|
|
14
|
+
dp.ctrlstat.write!(0x50000000)
|
|
15
|
+
dp.ctrlstat.read!(0xF0000000)
|
|
16
|
+
|
|
17
|
+
dp.select.bits(:addr).write!(0xF)
|
|
18
|
+
dp.select.read!
|
|
19
|
+
dp.select1.write! 4
|
|
20
|
+
dp.select1.read! 4
|
|
21
|
+
|
|
22
|
+
dp.abort.dapabort.write!(1)
|
|
23
|
+
|
|
24
|
+
ss "Tests of direct AP API"
|
|
25
|
+
ap = dut.arm_debugv6.mem_ap
|
|
26
|
+
|
|
27
|
+
ap.tar.write!(0x1234_0000)
|
|
28
|
+
|
|
29
|
+
ap.tar.read!
|
|
30
|
+
|
|
31
|
+
ss "Tests of high-level register API"
|
|
32
|
+
|
|
33
|
+
ss "Test write register, should write value 0xFF01"
|
|
34
|
+
dut.reg(:test).write!(0x0000FF01)
|
|
35
|
+
|
|
36
|
+
ss "Test write register with overlay, no subroutine"
|
|
37
|
+
dut.reg(:test).overlay('write_overlay')
|
|
38
|
+
dut.reg(:test).write!(0x0000FF01, no_subr: true)
|
|
39
|
+
dut.reg(:test).overlay(nil)
|
|
40
|
+
|
|
41
|
+
ss "Test write register with overlay, use subroutine if available"
|
|
42
|
+
dut.reg(:test).overlay('write_overlay_subr')
|
|
43
|
+
dut.reg(:test).write!(0x0000FF01)
|
|
44
|
+
dut.reg(:test).overlay(nil)
|
|
45
|
+
|
|
46
|
+
ss "Test read register, should read value 0x0000FF01"
|
|
47
|
+
dut.reg(:test).read!
|
|
48
|
+
|
|
49
|
+
ss "Test read register, with overlay, no subroutine, should read value 0x0000FF01"
|
|
50
|
+
dut.reg(:test).overlay('read_overlay')
|
|
51
|
+
dut.reg(:test).read!(no_subr: true)
|
|
52
|
+
dut.reg(:test).overlay(nil)
|
|
53
|
+
|
|
54
|
+
ss "Test read register, with overlay, use subroutine if available"
|
|
55
|
+
dut.reg(:test).overlay('read_overlay_subr')
|
|
56
|
+
dut.reg(:test).read!
|
|
57
|
+
dut.reg(:test).overlay(nil)
|
|
58
|
+
|
|
59
|
+
ss "Test read register with mask, should read value 0xXXXxxx1"
|
|
60
|
+
dut.reg(:test).read!(mask: 0x0000_000F)
|
|
61
|
+
|
|
62
|
+
ss "Test read register with store"
|
|
63
|
+
dut.reg(:test).store!
|
|
64
|
+
|
|
65
|
+
ss "Test bit level read, should read value 0xXXXxxx1"
|
|
66
|
+
dut.reg(:test).reset
|
|
67
|
+
dut.reg(:test).data = 0x0000FF01
|
|
68
|
+
dut.reg(:test)[0].read!
|
|
69
|
+
|
|
70
|
+
if Origen.app.target.name == 'dual_dp'
|
|
71
|
+
ss "SWITCHING DP"
|
|
72
|
+
dut.arm_debugv6.set_dp(:jtag)
|
|
73
|
+
|
|
74
|
+
ss "Test write register, should write value 0xFF01"
|
|
75
|
+
dut.reg(:test).write!(0x0000FF01)
|
|
76
|
+
|
|
77
|
+
ss "Test write register with overlay, no subroutine"
|
|
78
|
+
dut.reg(:test).overlay('write_overlay')
|
|
79
|
+
dut.reg(:test).write!(0x0000FF01, no_subr: true)
|
|
80
|
+
dut.reg(:test).overlay(nil)
|
|
81
|
+
|
|
82
|
+
ss "Test write register with overlay, use subroutine if available"
|
|
83
|
+
dut.reg(:test).overlay('write_overlay_subr')
|
|
84
|
+
dut.reg(:test).write!(0x0000FF01)
|
|
85
|
+
dut.reg(:test).overlay(nil)
|
|
86
|
+
|
|
87
|
+
ss "Test read register, should read value 0x0000FF01"
|
|
88
|
+
dut.reg(:test).read!
|
|
89
|
+
|
|
90
|
+
ss "Test read register, with overlay, no subroutine, should read value 0x0000FF01"
|
|
91
|
+
dut.reg(:test).overlay('read_overlay')
|
|
92
|
+
dut.reg(:test).read!(no_subr: true)
|
|
93
|
+
dut.reg(:test).overlay(nil)
|
|
94
|
+
|
|
95
|
+
ss "Test read register, with overlay, use subroutine if available"
|
|
96
|
+
dut.reg(:test).overlay('read_overlay_subr')
|
|
97
|
+
dut.reg(:test).read!
|
|
98
|
+
dut.reg(:test).overlay(nil)
|
|
99
|
+
|
|
100
|
+
ss "Test read register with mask, should read value 0xXXXxxx1"
|
|
101
|
+
dut.reg(:test).read!(mask: 0x0000_000F)
|
|
102
|
+
|
|
103
|
+
ss "Test read register with store"
|
|
104
|
+
dut.reg(:test).store!
|
|
105
|
+
|
|
106
|
+
ss "Test bit level read, should read value 0xXXXxxx1"
|
|
107
|
+
dut.reg(:test).reset
|
|
108
|
+
dut.reg(:test).data = 0x0000FF01
|
|
109
|
+
dut.reg(:test)[0].read!
|
|
110
|
+
|
|
111
|
+
ss "RESETTING DP (to default)"
|
|
112
|
+
dut.arm_debugv6.reset_dp
|
|
113
|
+
ss "Test bit level read, should read value 0xXXXxxx1"
|
|
114
|
+
dut.reg(:test).reset
|
|
115
|
+
dut.reg(:test).data = 0x0000FF01
|
|
116
|
+
dut.reg(:test)[0].read!
|
|
117
|
+
end
|
|
118
|
+
end
|
data/pattern/workout.rb
CHANGED
|
@@ -16,7 +16,11 @@ Pattern.create name: pattern_name do
|
|
|
16
16
|
dp.ctrlstat.write!(0x50000000)
|
|
17
17
|
dp.ctrlstat.read!(0xF0000000)
|
|
18
18
|
|
|
19
|
-
dp.select.apbanksel
|
|
19
|
+
if dp.select.has_bits?(:apbanksel)
|
|
20
|
+
dp.select.apbanksel.write!(0xF)
|
|
21
|
+
else
|
|
22
|
+
dp.select.bits(31..24).write!(0xF)
|
|
23
|
+
end
|
|
20
24
|
|
|
21
25
|
dp.abort.dapabort.write!(1)
|
|
22
26
|
|
data/templates/web/index.md.erb
CHANGED
|
@@ -138,6 +138,36 @@ instantiation_options[:dp_select_reset] = 0xC2_0D00
|
|
|
138
138
|
sub_block :arm_debug, instantiation_options
|
|
139
139
|
~~~
|
|
140
140
|
|
|
141
|
+
By default the acknowledge signature is masked (not compared). To enable comparison of the acknowledge signature during a read operation add this instantiation option:
|
|
142
|
+
|
|
143
|
+
~~~ruby
|
|
144
|
+
mem_aps = {
|
|
145
|
+
mem_ap: { base_address: 0x00000000 }
|
|
146
|
+
mem2_ap: { base_address: 0x10000000 }
|
|
147
|
+
}
|
|
148
|
+
instantiation_options[:class_name] = 'OrigenARMDebug::DAP'
|
|
149
|
+
instantiation_options[:mem_aps] = mem_aps
|
|
150
|
+
|
|
151
|
+
instantiation_options[:read_ack] = true # Check for the acknowledge signature when reading an AP
|
|
152
|
+
|
|
153
|
+
sub_block :arm_debug, instantiation_options
|
|
154
|
+
~~~
|
|
155
|
+
|
|
156
|
+
DAP Version 6 instantiation example:
|
|
157
|
+
|
|
158
|
+
~~~ruby
|
|
159
|
+
mem_aps = {
|
|
160
|
+
mem_ap: { base_address: 0x001C_1000 }
|
|
161
|
+
mem2_ap: { base_address: 0x001C_2000 }
|
|
162
|
+
}
|
|
163
|
+
instantiation_options[:class_name] = 'OrigenARMDebug::DAP'
|
|
164
|
+
instantiation_options[:mem_aps] = mem_aps
|
|
165
|
+
|
|
166
|
+
instantiation_options[:dapv6] = true
|
|
167
|
+
|
|
168
|
+
sub_block :arm_debug, instantiation_options
|
|
169
|
+
~~~
|
|
170
|
+
|
|
141
171
|
### Company Customization
|
|
142
172
|
|
|
143
173
|
It may be the case that your application needs additional, customized Access Ports (AP) which are allowed but
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: origen_arm_debug
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ronnie Lajaunie
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-10-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: origen
|
|
@@ -87,11 +87,14 @@ files:
|
|
|
87
87
|
- lib/origen_arm_debug/dap.rb
|
|
88
88
|
- lib/origen_arm_debug/dap_controller.rb
|
|
89
89
|
- lib/origen_arm_debug/dp_controller.rb
|
|
90
|
+
- lib/origen_arm_debug/dp_controller_v6.rb
|
|
90
91
|
- lib/origen_arm_debug/helpers.rb
|
|
91
92
|
- lib/origen_arm_debug/jtag_ap.rb
|
|
92
93
|
- lib/origen_arm_debug/jtag_ap_controller.rb
|
|
93
94
|
- lib/origen_arm_debug/jtag_dp.rb
|
|
94
95
|
- lib/origen_arm_debug/jtag_dp_controller.rb
|
|
96
|
+
- lib/origen_arm_debug/jtag_dp_v6.rb
|
|
97
|
+
- lib/origen_arm_debug/jtag_dp_v6_controller.rb
|
|
95
98
|
- lib/origen_arm_debug/mem_ap.rb
|
|
96
99
|
- lib/origen_arm_debug/mem_ap_controller.rb
|
|
97
100
|
- lib/origen_arm_debug/sw_dp.rb
|
|
@@ -100,7 +103,9 @@ files:
|
|
|
100
103
|
- lib/origen_arm_debug_dev/dut_dual_dp.rb
|
|
101
104
|
- lib/origen_arm_debug_dev/dut_jtag.rb
|
|
102
105
|
- lib/origen_arm_debug_dev/dut_jtag_axi.rb
|
|
106
|
+
- lib/origen_arm_debug_dev/dut_jtag_axi_ack.rb
|
|
103
107
|
- lib/origen_arm_debug_dev/dut_swd.rb
|
|
108
|
+
- pattern/v6_workout.rb
|
|
104
109
|
- pattern/workout.rb
|
|
105
110
|
- templates/web/index.md.erb
|
|
106
111
|
- templates/web/layouts/_basic.html.erb
|
|
@@ -118,14 +123,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
118
123
|
requirements:
|
|
119
124
|
- - ">="
|
|
120
125
|
- !ruby/object:Gem::Version
|
|
121
|
-
version:
|
|
126
|
+
version: '0'
|
|
122
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
128
|
requirements:
|
|
124
129
|
- - ">="
|
|
125
130
|
- !ruby/object:Gem::Version
|
|
126
|
-
version:
|
|
131
|
+
version: '0'
|
|
127
132
|
requirements: []
|
|
128
|
-
rubygems_version: 3.1.
|
|
133
|
+
rubygems_version: 3.1.6
|
|
129
134
|
signing_key:
|
|
130
135
|
specification_version: 4
|
|
131
136
|
summary: Provides an Origen API to perform register read and write operations via
|