origen_arm_debug 0.4.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 609583b64578afdec4453eaec6425e0eb3ea447c
4
+ data.tar.gz: fcb99fc0d5ebaf867853fb59055b0a9ee7fc519d
5
+ SHA512:
6
+ metadata.gz: 2c0c1690d203d8ef3443927bfce7602e1cd6317c736200aa5dc263dd185611a63e97f9f5e4f1bdd0e0eb1690336b7eb93aa9ecf3621d5db372c9bd0c1fb32b9b
7
+ data.tar.gz: a25d97c6b5791a6418df1954c599b635cf93035cf2a0de695b9b4be8357fc42d66ac993ed53bad71f750c52c7dc3d3bfcc7175927d4fcbe00bc62a9c74a14c9a
@@ -0,0 +1,59 @@
1
+ class OrigenARMDebugApplication < Origen::Application
2
+
3
+ # This information is used in headers and email templates, set it specific
4
+ # to your application
5
+ config.name = "Origen ARM Debug"
6
+ config.initials = "OrigenARMDebug"
7
+
8
+ self.name = "origen_arm_debug"
9
+ self.namespace = "OrigenARMDebug"
10
+ config.rc_url = "git@github.com:Origen-SDK/origen_arm_debug.git"
11
+ config.release_externally = true
12
+
13
+ # To enable deployment of your documentation to a web server (via the 'origen web'
14
+ # command) fill in these attributes.
15
+ config.web_directory = "git@github.com:Origen-SDK/Origen-SDK.github.io.git/arm_debug"
16
+ config.web_domain = "http://origen-sdk.org/arm_debug"
17
+
18
+ config.semantically_version = true
19
+
20
+ config.lint_test = {
21
+ # Require the lint tests to pass before allowing a release to proceed
22
+ run_on_tag: true,
23
+ # Auto correct violations where possible whenever 'origen lint' is run
24
+ auto_correct: true,
25
+ # Limit the testing for large legacy applications
26
+ level: :easy,
27
+ # Run on these directories/files by default
28
+ #files: ["lib", "config/application.rb"],
29
+ }
30
+
31
+ # Ensure that all tests pass before allowing a release to continue
32
+ def validate_release
33
+ if !system("origen examples") #|| !system("origen specs")
34
+ puts "Sorry but you can't release with failing tests, please fix them and try again."
35
+ exit 1
36
+ else
37
+ puts "All tests passing, proceeding with release process!"
38
+ end
39
+ end
40
+
41
+ # Run code coverage when deploying the web site
42
+ def before_deploy_site
43
+ Dir.chdir Origen.root do
44
+ system "origen examples -c"
45
+ dir = "#{Origen.root}/web/output/coverage"
46
+ FileUtils.remove_dir(dir, true) if File.exists?(dir)
47
+ system "mv #{Origen.root}/coverage #{dir}"
48
+ end
49
+ end
50
+
51
+ # Deploy the website automatically after a production tag
52
+ def after_release_email(tag, note, type, selector, options)
53
+ command = "origen web compile --remote --api"
54
+ Dir.chdir Origen.root do
55
+ system command
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,51 @@
1
+ # This file should be used to extend the origen command line tool with tasks
2
+ # specific to your application.
3
+ #
4
+ # Also see the official docs on adding commands:
5
+ # http://origen-sdk.org/origen/latest/guides/custom/commands/
6
+
7
+ # Map any command aliases here, for example to allow origen -x to refer to a
8
+ # command called execute you would add a reference as shown below:
9
+ aliases ={
10
+ # "-x" => "execute",
11
+ }
12
+
13
+ # The requested command is passed in here as @command, this checks it against
14
+ # the above alias table and should not be removed.
15
+ @command = aliases[@command] || @command
16
+
17
+ # Now branch to the specific task code
18
+ case @command
19
+
20
+ when "examples"
21
+ Origen.load_application
22
+ status = 0
23
+
24
+ # Pattern generator tests
25
+ ARGV = %w(read_write_reg -t debug -r approved)
26
+ load "#{Origen.top}/lib/origen/commands/generate.rb"
27
+
28
+ if Origen.app.stats.changed_files == 0 &&
29
+ Origen.app.stats.new_files == 0 &&
30
+ Origen.app.stats.changed_patterns == 0 &&
31
+ Origen.app.stats.new_patterns == 0
32
+
33
+ Origen.app.stats.report_pass
34
+ else
35
+ Origen.app.stats.report_fail
36
+ status = 1
37
+ end
38
+ puts
39
+ exit status
40
+
41
+ # Always leave an else clause to allow control to fall back through to the
42
+ # Origen command handler.
43
+ # You probably want to also add the command details to the help shown via
44
+ # origen -h, you can do this be assigning the required text to @application_commands
45
+ # before handing control back to Origen. Un-comment the example below to get started.
46
+ else
47
+ @application_commands = <<-EOT
48
+ examples Run the examples (tests), -c will enable coverage
49
+ EOT
50
+
51
+ end
@@ -0,0 +1,17 @@
1
+ # This file is similar to environment.rb and will be loaded
2
+ # automatically at the start of each invocation of Origen.
3
+ #
4
+ # However the major difference is that it will not be loaded
5
+ # if the application is imported by a 3rd party app - in that
6
+ # case only environment.rb is loaded.
7
+ #
8
+ # Therefore this file should be used to load anything you need
9
+ # to setup a development environment for this app, normally
10
+ # this would be used to define some dummy classes to instantiate
11
+ # your objects so that they can be tested and/or interacted with
12
+ # in the console.
13
+ module OrigenARMDebug
14
+ autoload :DUT, "origen_arm_debug/dut"
15
+ autoload :JTAG_DUT, "origen_arm_debug/dut_jtag"
16
+ autoload :SWD_DUT, "origen_arm_debug/dut_swd"
17
+ end
@@ -0,0 +1,3 @@
1
+ require "origen_arm_debug"
2
+
3
+
data/config/users.rb ADDED
@@ -0,0 +1,19 @@
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
data/config/version.rb ADDED
@@ -0,0 +1,8 @@
1
+ module OrigenARMDebug
2
+ MAJOR = 0
3
+ MINOR = 4
4
+ BUGFIX = 0
5
+ DEV = nil
6
+
7
+ VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
+ end
@@ -0,0 +1,16 @@
1
+ require 'origen'
2
+ require_relative '../config/application.rb'
3
+ require 'origen_jtag'
4
+ require 'origen_swd'
5
+
6
+ # Include this module to add a ARM Debug driver to your class
7
+ module OrigenARMDebug
8
+ autoload :Driver, 'origen_arm_debug/driver'
9
+ autoload :SWJ_DP, 'origen_arm_debug/swj_dp'
10
+ autoload :MemAP, 'origen_arm_debug/mem_ap'
11
+
12
+ # Returns an instance of the OrigenARMDebug::Driver
13
+ def arm_debug
14
+ @arm_debug ||= Driver.new(self)
15
+ end
16
+ end
@@ -0,0 +1,255 @@
1
+ module OrigenARMDebug
2
+ class ABSIF_JTAG
3
+ JTAGC_ARM_ABORT = 0b1000
4
+ JTAGC_ARM_DPACC = 0b1010
5
+ JTAGC_ARM_APACC = 0b1011
6
+ JTAGC_ARM_IDCODE = 0b1110
7
+ JTAGC_ARM_BYPASS = 0b1111
8
+
9
+ attr_reader :owner
10
+ attr_accessor :write_ap_dly
11
+ attr_accessor :acc_access_dly
12
+
13
+ def initialize(owner, options = {})
14
+ @owner = owner
15
+
16
+ @write_ap_dly = 8
17
+ @acc_access_dly = 7
18
+
19
+ @current_apaddr = 0x00000000
20
+ end
21
+
22
+ #-------------------------------------
23
+ # Read tasks - high level
24
+ #-------------------------------------
25
+ def R_dp(name, rdata, options = {})
26
+ options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
27
+ read_dp(name, rdata, options)
28
+ end
29
+
30
+ def RE_dp(name, edata, options = {})
31
+ options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
32
+ actual = edata
33
+ R_dp(name, actual, options)
34
+
35
+ cc "ABS-IF: RE-DP: #{name} = 0x#{actual.to_s(16).rjust(8, '0')}, "\
36
+ "expected = 0x#{edata.to_s(16).rjust(8, '0')}, "\
37
+ "mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
38
+ end
39
+
40
+ def R_ap(addr, rdata, options = {})
41
+ options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
42
+ read_ap(addr, rdata, options)
43
+ end
44
+
45
+ def RE_ap(addr, edata, options = {})
46
+ options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
47
+ actual = edata
48
+ R_ap(addr, actual, options)
49
+
50
+ cc "ABS-IF: RE-AP: addr = 0x#{addr.to_s(16).rjust(8, '0')}, "\
51
+ "actual = 0x#{actual.to_s(16).rjust(8, '0')}, "\
52
+ "expected = 0x#{edata.to_s(16).rjust(8, '0')}, "\
53
+ "mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
54
+ end
55
+
56
+ def WAIT_RE_ap(addr, edata, options = {})
57
+ options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
58
+ actual = edata
59
+ R_ap(addr, actual, options)
60
+
61
+ cc "ABS-IF: WAIT_RE-AP: addr = 0x#{addr.to_s(16).rjust(8, '0')}, "\
62
+ "actual = 0x#{actual.to_s(16).rjust(8, '0')}, "\
63
+ "expected = 0x#{edata.to_s(16).rjust(8, '0')}, "\
64
+ "mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
65
+ end
66
+
67
+ #-------------------------------------
68
+ # Write tasks - high level
69
+ #-------------------------------------
70
+ def W_dp(name, wdata, options = {})
71
+ options = { w_attempts: 1 }.merge(options)
72
+ write_dp(name, wdata, options)
73
+ end
74
+
75
+ def WR_dp(name, wdata, options = {})
76
+ options = { edata: 0x00000000, mask: 0xffffffff, w_attempts: 1, r_attempts: 1 }.merge(options)
77
+ actual = options[:edata] & options[:mask]
78
+
79
+ W_dp(name, wdata, options)
80
+ R_dp(name, actual, options)
81
+
82
+ cc "ABS-IF: WR-DP: #{name} write = 0x#{wdata.to_s(16).rjust(8, '0')}, "\
83
+ "read = 0x#{actual.to_s(16).rjust(8, '0')}, "\
84
+ "expected = 0x#{options[:edata].to_s(16).rjust(8, '0')}, "\
85
+ "mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
86
+ end
87
+
88
+ def W_ap(addr, wdata, options = {})
89
+ options = { w_attempts: 1 }.merge(options)
90
+ write_ap(addr, wdata, options)
91
+ end
92
+
93
+ def WR_ap(addr, wdata, options = {})
94
+ options = { edata: 0x00000000, mask: 0xffffffff, w_attempts: 1, r_attempts: 1 }.merge(options)
95
+ actual = wdata & options[:mask]
96
+
97
+ W_ap(addr, wdata, options)
98
+ R_ap(addr, actual, options)
99
+
100
+ cc "ABS-IF: WR-AP: addr = 0x#{addr.to_s(16).rjust(8, '0')}, "\
101
+ "write = 0x#{wdata.to_s(16).rjust(8, '0')}, "\
102
+ "read = 0x#{actual.to_s(16).rjust(8, '0')}, "\
103
+ "expected = 0x#{options[:edata].to_s(16).rjust(8, '0')}, "\
104
+ "mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
105
+ end
106
+
107
+ private
108
+
109
+ #-------------------------------------
110
+ # Implementation of virtual functions
111
+ #-------------------------------------
112
+ def read_dp(name, rdata, options = {})
113
+ options = { r_attempts: 1 }.merge(options)
114
+
115
+ set_ir(name) if name == 'IDCODE'
116
+ case name
117
+ when 'ABORT' then puts "#{name} JTAG-DP register is write-only"
118
+ when 'CTRL/STAT' then dpacc_access(name, 1, random, rdata, options)
119
+ when 'SELECT' then dpacc_access(name, 1, random, rdata, options)
120
+ when 'RDBUFF' then dpacc_access(name, 1, random, rdata, options)
121
+ when 'IDCODE' then owner.owner.jtag.write_dr(random, size: 32) # need to make parameterized!!!
122
+ else
123
+ puts "Unknown JTAG-DP register name #{name}"
124
+ end
125
+ if name != 'IDCODE' && name != 'RDBUFF'
126
+ read_dp('RDBUFF', rdata, options)
127
+ end
128
+ cc "ABS-IF: R-DP: #{name}=0x" + rdata.to_s(16).rjust(8, '0')
129
+ end
130
+
131
+ def write_dp(name, wdata, options = {})
132
+ options = { w_attempts: 1 }.merge(options)
133
+
134
+ if name == 'ABORT' && wdata != 0x00000001
135
+ puts "#{name} register must only ever be written with the value 0x00000001"
136
+ end
137
+ case name
138
+ when 'ABORT' then dpacc_access(name, 0, wdata, random, options)
139
+ when 'CTRL/STAT' then dpacc_access(name, 0, wdata, random, options)
140
+ when 'SELECT' then dpacc_access(name, 0, wdata, random, options)
141
+ when 'RDBUFF' then puts "#{name} JTAG-DP register is read-only"
142
+ when 'IDCODE' then puts "#{name} JTAG-DP register is read-only"
143
+ else; puts "Unknown JTAG-DP register name #{name}"
144
+ end
145
+ cc "ABS-IF: W-DP: #{name} = 0x#{wdata.to_s(16).rjust(8, '0')}"
146
+ end
147
+
148
+ def read_ap(addr, rdata, options = {});
149
+ options = { r_attempts: 1 }.merge(options)
150
+
151
+ apacc_access(addr, 1, random, rdata, options)
152
+ read_dp('RDBUFF', rdata, options)
153
+
154
+ cc "ABS-IF: R-AP: addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
155
+ "rdata=0x#{rdata.to_s(16).rjust(8, '0')}"
156
+ end
157
+
158
+ def write_ap(addr, wdata, options = {});
159
+ options = { w_attempts: 1 }.merge(options)
160
+
161
+ rdata = 0x00000000
162
+ apacc_access(addr, 0, wdata, rdata, options);
163
+ $tester.cycle(repeat: @write_ap_dly)
164
+
165
+ cc "ABS-IF: W-AP: addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
166
+ "wdata=0x#{wdata.to_s(16).rjust(8, '0')}"
167
+ end
168
+
169
+ #-------------------------------------
170
+ # lower level helper tasks
171
+ #-------------------------------------
172
+ def set_ir(name)
173
+ new_ir = get_ir_code(name);
174
+ owner.owner.jtag.write_ir(new_ir, size: 4) # need to make parameterized!!!
175
+ end
176
+
177
+ def acc_access(name, addr, rwb, wdata, rdata, attempts, options = {});
178
+ set_ir(name);
179
+ concat_data = (wdata << 3) | (addr << 1) | rwb
180
+ attempts.times do
181
+ if name == 'RDBUFF'
182
+ r = $dut.reg(:dap)
183
+ if options[:r_mask] == 'store'
184
+ r.bits(3..34).store
185
+ elsif options.key?(:compare_data)
186
+ r.bits(3..34).data = options[:compare_data]
187
+ end
188
+ options = options.merge(size: r.size)
189
+ owner.owner.jtag.read_dr(r, options) # need to make parameterized!!!
190
+ else
191
+ options = options.merge(size: 35)
192
+ owner.owner.jtag.write_dr(concat_data, options) # need to make parameterized!!!
193
+ end
194
+ end
195
+ $tester.cycle(repeat: @acc_access_dly)
196
+ end
197
+
198
+ def dpacc_access(name, rwb, wdata, rdata, options = {});
199
+ attempts = options[:r_attempts].nil? ? (options[:w_attempts].nil? ? 1 : options[:w_attempts]) : options[:r_attempts]
200
+ addr = get_dp_addr(name);
201
+ addr_3_2 = (addr & 0x0C) >> 2
202
+ acc_access(name, addr_3_2, rwb, wdata, rdata, attempts, options);
203
+ end
204
+
205
+ def set_apselect(addr);
206
+ _random = random
207
+ addr = addr & 0xff0000f0;
208
+ concat_data = (addr & 0xff000000) | (_random & 0x00ffff00) | (addr & 0x000000f0) | (_random & 0x0000000f)
209
+ if (addr != @current_apaddr)
210
+ write_dp('SELECT', concat_data);
211
+ end
212
+ @current_apaddr = addr;
213
+ end
214
+
215
+ def apacc_access(addr, rwb, wdata, rdata, options = {});
216
+ attempts = options[:r_attempts].nil? ? (options[:w_attempts].nil? ? 1 : options[:w_attempts]) : options[:r_attempts]
217
+ set_apselect(addr);
218
+ addr_3_2 = (addr & 0x0000000C) >> 2
219
+ acc_access('APACC', addr_3_2, rwb, wdata, rdata, attempts, options);
220
+ end
221
+
222
+ def get_dp_addr(name);
223
+ case name
224
+ when 'IDCODE' then return 0xF
225
+ when 'CTRL/STAT' then return 0x4
226
+ when 'SELECT' then return 0x8
227
+ when 'RDBUFF' then return 0xC
228
+ when 'ABORT' then return 0x0
229
+ when 'WCR' then puts "#{name} is a SW-DP only register"
230
+ when 'RESEND' then puts "#{name} is a SW-DP only register"
231
+ else; puts "Unknown JTAG-DP register name: #{name}"
232
+ end
233
+ 0
234
+ end
235
+
236
+ def get_ir_code(name);
237
+ case name
238
+ when 'ABORT' then return JTAGC_ARM_ABORT
239
+ when 'CTRL/STAT' then return JTAGC_ARM_DPACC
240
+ when 'SELECT' then return JTAGC_ARM_DPACC
241
+ when 'RDBUFF' then return JTAGC_ARM_DPACC
242
+ when 'APACC' then return JTAGC_ARM_APACC
243
+ when 'IDCODE' then return JTAGC_ARM_IDCODE
244
+ when 'RESEND' then puts "#{name} is a SW-DP only register"
245
+ else; puts "Unknown JTAG-DP register name: #{name}"
246
+ end
247
+ 0
248
+ end
249
+
250
+ def random
251
+ # rand(4294967295) # random 32-bit integer
252
+ 0x01234567
253
+ end
254
+ end
255
+ end