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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b9c86cc50df6d0c06e836b469ac5c5505538507
4
- data.tar.gz: 5ff8f7838d12c691a28d5b32129762391e0c0413
3
+ metadata.gz: 06b61282c9205efdb49a4a8cd5532e9dc718b7f6
4
+ data.tar.gz: 525f141f5fb7002bb9af7809ae71af1e2a71cdc1
5
5
  SHA512:
6
- metadata.gz: c607efbf26b27c0d7c178d6c3eb825c5e57d7568031a91bc6ca42be0e701fea7fcc138a7116d6a5f0a6537b28deb231bd77991a064f24f37f956c9d9732ec805
7
- data.tar.gz: 10f47615a8dadfe981bf165c9edde516f4fbf3c23dc04836e1e42972be98b362dd12fd6112e24a7cf59599e35548578e0e3a043b48806f4540cc2b99d56252ce
6
+ metadata.gz: 02092bbc25a5b1da0e119445204a2cc47bb03426de293dd16e9495611038db7162604e5209f1031ccf4ef5f87040fc088992abea497c572acdddb5a196b2e127
7
+ data.tar.gz: da718b20deba251a76896c7c10031b9b9c154f1dbb4da68fc5634328c16823f651b906d759093fe61b169f5e16de17aea8db22db2e21236715f73c901cc2726b
@@ -23,14 +23,14 @@ class OrigenARMDebugApplication < Origen::Application
23
23
  # Auto correct violations where possible whenever 'origen lint' is run
24
24
  auto_correct: true,
25
25
  # Limit the testing for large legacy applications
26
- level: :easy,
26
+ #level: :easy,
27
27
  # Run on these directories/files by default
28
28
  #files: ["lib", "config/application.rb"],
29
29
  }
30
30
 
31
31
  # Ensure that all tests pass before allowing a release to continue
32
32
  def validate_release
33
- if !system("origen examples") || !system("origen specs")
33
+ if !system("origen examples") # || !system("origen specs")
34
34
  puts "Sorry but you can't release with failing tests, please fix them and try again."
35
35
  exit 1
36
36
  else
@@ -42,7 +42,7 @@ class OrigenARMDebugApplication < Origen::Application
42
42
  def before_deploy_site
43
43
  Dir.chdir Origen.root do
44
44
  system "origen examples -c"
45
- system "origen specs -c"
45
+ # system "origen specs -c"
46
46
  dir = "#{Origen.root}/web/output/coverage"
47
47
  FileUtils.remove_dir(dir, true) if File.exists?(dir)
48
48
  system "mv #{Origen.root}/coverage #{dir}"
data/config/boot.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "origen_arm_debug"
2
+
3
+ require "origen_arm_debug_dev/dut"
4
+ require "origen_arm_debug_dev/dut_jtag"
5
+ require "origen_arm_debug_dev/dut_swd"
data/config/commands.rb CHANGED
@@ -17,20 +17,18 @@ aliases ={
17
17
  # Now branch to the specific task code
18
18
  case @command
19
19
 
20
- when "specs"
21
- require "rspec"
22
- exit RSpec::Core::Runner.run(['spec'])
20
+ # when "specs"
21
+ # require "rspec"
22
+ # exit RSpec::Core::Runner.run(['spec'])
23
23
 
24
- when "examples"
24
+ when "examples" # , "test"
25
25
  Origen.load_application
26
26
  status = 0
27
27
 
28
28
  # Pattern generator tests
29
- ARGV = %w(read_write_reg -t debug -r approved)
29
+ ARGV = %w(workout -t jtag -e j750 -r approved)
30
30
  load "#{Origen.top}/lib/origen/commands/generate.rb"
31
- ARGV = %w(read_write_reg_jtag -t jtag -r approved)
32
- load "#{Origen.top}/lib/origen/commands/generate.rb"
33
- ARGV = %w(read_write_reg_swd -t swd -r approved)
31
+ ARGV = %w(workout -t swd -e j750 -r approved)
34
32
  load "#{Origen.top}/lib/origen/commands/generate.rb"
35
33
 
36
34
  if Origen.app.stats.changed_files == 0 &&
@@ -44,6 +42,12 @@ when "examples"
44
42
  status = 1
45
43
  end
46
44
  puts
45
+ # if @command == "test"
46
+ # Origen.app.unload_target!
47
+ # require "rspec"
48
+ # result = RSpec::Core::Runner.run(['spec'])
49
+ # status = status == 1 ? 1 : result
50
+ # end
47
51
  exit status
48
52
 
49
53
  # Always leave an else clause to allow control to fall back through to the
@@ -52,8 +56,9 @@ when "examples"
52
56
  # origen -h, you can do this be assigning the required text to @application_commands
53
57
  # before handing control back to Origen. Un-comment the example below to get started.
54
58
  else
59
+ #specs Run the specs (unit tests), -c will enable coverage
60
+ #test Run both specs and examples, -c will enable coverage
55
61
  @application_commands = <<-EOT
56
- specs Run the specs (unit tests), -c will enable coverage
57
62
  examples Run the examples (tests), -c will enable coverage
58
63
  EOT
59
64
 
data/config/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module OrigenARMDebug
2
- MAJOR = 0
3
- MINOR = 10
4
- BUGFIX = 1
5
- DEV = nil
2
+ MAJOR = 1
3
+ MINOR = 0
4
+ BUGFIX = 0
5
+ DEV = 1
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
8
  end
@@ -3,14 +3,10 @@ require_relative '../config/application.rb'
3
3
  require 'origen_jtag'
4
4
  require 'origen_swd'
5
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
6
+ require 'origen_arm_debug/helpers'
7
+ require 'origen_arm_debug/dap'
8
+ require 'origen_arm_debug/jtag_dp'
9
+ require 'origen_arm_debug/sw_dp'
10
+ require 'origen_arm_debug/ap.rb'
11
+ require 'origen_arm_debug/mem_ap'
12
+ require 'origen_arm_debug/jtag_ap'
@@ -0,0 +1,14 @@
1
+ require 'origen_arm_debug/ap_controller'
2
+ module OrigenARMDebug
3
+ # Generic Access Port (AP)
4
+ class AP
5
+ include Origen::Model
6
+
7
+ # Wait states for data to be transferred from AP-Reg to RDBUFF (on read)
8
+ attr_reader :apreg_access_wait
9
+
10
+ def initialize(options = {})
11
+ @apreg_access_wait = options[:apreg_access_wait] || 0
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ module OrigenARMDebug
2
+ class APController
3
+ include Origen::Controller
4
+ include Helpers
5
+
6
+ def write_register(reg_or_val, options = {})
7
+ if reg_or_val.try(:owner) == model
8
+ log "Write AP (#{model.name}) register #{reg_or_val.name.to_s.upcase}: #{reg_or_val.data.to_hex}" do
9
+ parent.dp.write_register(reg_or_val)
10
+ apreg_access_wait.cycles
11
+ end
12
+ else
13
+ fail 'No Resource-specific transport defined for MDM-AP (#model.name})'
14
+ end
15
+ end
16
+
17
+ def read_register(reg_or_val, options = {})
18
+ if reg_or_val.try(:owner) == model
19
+ log "Read AP (#{model.name}) register #{reg_or_val.name.to_s.upcase}: #{Origen::Utility.read_hex(reg_or_val)}" do
20
+ parent.dp.read_register(reg_or_val, apacc_wait_states: apreg_access_wait)
21
+ end
22
+ else
23
+ fail 'No Resource-specific transport defined for MDM-AP (#model.name})'
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,89 @@
1
+ require 'origen_arm_debug/dap_controller'
2
+ module OrigenARMDebug
3
+ # This is the top-level model that instantiates the DP and APs
4
+ class DAP
5
+ include Origen::Model
6
+
7
+ attr_reader :dps, :mem_aps, :jtag_aps, :ext_aps
8
+
9
+ def initialize(options = {})
10
+ @dps = []
11
+ @mem_aps = [] # Array of MEM-APs
12
+ @jtag_aps = [] # Array of JTAG-APs
13
+ @ext_aps = [] # Array of 'extension' APs
14
+ instantiate_subblocks(options)
15
+ end
16
+
17
+ def instantiate_subblocks(options = {})
18
+ if options[:swd] || parent.respond_to?(:swd)
19
+ dps << sub_block(:sw_dp, class_name: 'OrigenARMDebug::SW_DP')
20
+ end
21
+
22
+ if options[:jtag] || parent.respond_to?(:jtag)
23
+ dps << sub_block(:jtag_dp, class_name: 'OrigenARMDebug::JTAG_DP')
24
+ end
25
+
26
+ Array(options[:mem_aps]).each do |name, base_address|
27
+ if base_address.is_a?(Hash)
28
+ ap_opts = { class_name: 'OrigenARMDebug::MemAP' }.merge(base_address)
29
+ else
30
+ ap_opts = { class_name: 'OrigenARMDebug::MemAP', base_address: base_address }
31
+ end
32
+
33
+ add_ap(name, ap_opts)
34
+ end
35
+
36
+ Array(options[:jtag_aps]).each do |name, base_address|
37
+ if base_address.is_a?(Hash)
38
+ ap_opts = { class_name: 'OrigenARMDebug::JTAGAP' }.merge(base_address)
39
+ else
40
+ ap_opts = { class_name: 'OrigenARMDebug::JTAGAP', base_address: base_address }
41
+ end
42
+
43
+ add_ap(name, ap_opts)
44
+ end
45
+
46
+ Array(options[:aps]).each do |name, opts|
47
+ if opts.is_a?(Hash)
48
+ klass = opts.delete(:class_name)
49
+ addr = opts.delete(:base_address)
50
+ if klass.nil? || addr.nil?
51
+ fail "[ARM DEBUG] Error: Must specify class_name and base_address if using 'aps' hash to define APs"
52
+ end
53
+ ap_opts = { class_name: klass, base_address: addr }.merge(opts)
54
+ else
55
+ fail "[ARM DEBUG] Error: Must specify class_name and base_address if using 'aps' hash to define APs"
56
+ end
57
+
58
+ add_ap(name, ap_opts)
59
+ end
60
+ end
61
+
62
+ # Method to add additional Access Ports (MEM-AP)
63
+ #
64
+ # @param [Integer] name Short name for mem_ap that is being created
65
+ # @param [Hash] options Implemenation specific details
66
+ #
67
+ # @examples
68
+ # arm_debug.add_ap('alt_ahbapi', { class_name: 'OrigenARMDebug::MemAP', base_address: 0x02000000 })
69
+ #
70
+ def add_ap(name, options)
71
+ domain name.to_sym
72
+ ap = sub_block(name.to_sym, options)
73
+
74
+ if options[:class_name] == 'OrigenARMDebug::MemAP'
75
+ mem_aps << ap
76
+ elsif options[:class_name] == 'OrigenARMDebug::JTAGAP'
77
+ jtag_aps << ap
78
+ else
79
+ ext_aps << ap
80
+ end
81
+ end
82
+
83
+ # Returns an array containing all APs
84
+ def aps
85
+ mem_aps + jtag_aps + ext_aps
86
+ end
87
+ end
88
+ Driver = DAP # For legacy API compatibility
89
+ end
@@ -0,0 +1,14 @@
1
+ module OrigenARMDebug
2
+ class DAPController
3
+ include Origen::Controller
4
+ include Helpers
5
+
6
+ # Returns the currently enabled DP (or the only DP if only one
7
+ # of them).
8
+ # If no dp is enabled before calling this, it will choose the
9
+ # SW_DP by default.
10
+ def dp
11
+ dps.first
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module OrigenARMDebug
2
+ # Common methods shared between the SW and JTAG DP controllers
3
+ module DPController
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
12
+ if model.select.data != address
13
+ model.select.write!(address)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ module OrigenARMDebug
2
+ # Generic helper methods shared by the various controllers
3
+ module Helpers
4
+ def extract_data(reg_or_val, options = {})
5
+ if reg_or_val.respond_to?('data')
6
+ reg_or_val.data
7
+ else
8
+ reg_or_val
9
+ end
10
+ end
11
+
12
+ def extract_address(reg_or_val, options = {})
13
+ addr = options[:address] || options[:addr]
14
+ return addr if addr
15
+ return reg_or_val.address if reg_or_val.respond_to?('address')
16
+ return reg_or_val.addr if reg_or_val.respond_to?('addr')
17
+ fail 'No address given, if supplying a data value instead of a register object, you must supply an :address option'
18
+ end
19
+
20
+ def log(msg)
21
+ cc "[ARM Debug] #{msg}"
22
+ if block_given?
23
+ yield
24
+ cc "[ARM Debug] /#{msg}"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,10 @@
1
+ require 'origen_arm_debug/jtag_ap_controller'
2
+ module OrigenARMDebug
3
+ class JTAGAP < AP
4
+ include Origen::Model
5
+
6
+ def initialize(options = {})
7
+ super
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ module OrigenARMDebug
2
+ class JTAGAPController
3
+ include Origen::Controller
4
+ include Helpers
5
+ end
6
+ end
@@ -0,0 +1,59 @@
1
+ require 'origen_arm_debug/jtag_dp_controller'
2
+ module OrigenARMDebug
3
+ class JTAG_DP
4
+ include Origen::Model
5
+
6
+ def initialize(options = {})
7
+ add_reg :ir, 0, size: 4
8
+
9
+ # Virtual reg used to represent all of the various 35-bit scan chains
10
+ reg :dr, 0, size: 35 do |reg|
11
+ reg.bit 34..3, :data
12
+ reg.bit 2..1, :a
13
+ reg.bit 0, :rnw
14
+ end
15
+
16
+ reg :idcode, 0b1110, access: :ro do |reg|
17
+ reg.bit 31..28, :version
18
+ reg.bit 27..12, :partno
19
+ reg.bit 11..1, :designer
20
+ reg.bit 0, :bit0, reset: 1
21
+ end
22
+
23
+ reg :ctrlstat, 0x4 do |reg|
24
+ reg.bit 31, :csyspwrupack
25
+ reg.bit 30, :csyspwrupreq
26
+ reg.bit 29, :cdbgpwrupack
27
+ reg.bit 28, :cdbgpwrupreq
28
+ reg.bit 27, :cdbgrstack
29
+ reg.bit 26, :cdbgrstreq
30
+ reg.bit 23..12, :trncnt
31
+ reg.bit 11..8, :masklane
32
+ reg.bit 5, :stickyerr
33
+ reg.bit 4, :stickycmp
34
+ reg.bit 3..2, :trnmode
35
+ reg.bit 1, :stickyorun
36
+ reg.bit 0, :orundetect
37
+ end
38
+
39
+ reg :select, 0x8 do |reg|
40
+ reg.bit 31..24, :apsel
41
+ reg.bit 7..4, :apbanksel
42
+ end
43
+
44
+ add_reg :rdbuff, 0xC, access: :ro, reset: 0
45
+
46
+ reg :abort, 0b1000, access: :wo do |reg|
47
+ reg.bit 0, :dapabort
48
+ end
49
+ end
50
+
51
+ def select
52
+ reg(:select)
53
+ end
54
+
55
+ def abort
56
+ reg(:abort)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,140 @@
1
+ require 'origen_arm_debug/dp_controller'
2
+ module OrigenARMDebug
3
+ class JTAG_DPController
4
+ include Origen::Controller
5
+ include Helpers
6
+ include DPController
7
+
8
+ def write_register(reg, options = {})
9
+ unless reg.writable?
10
+ fail "The :#{reg.name} register is not writeable!"
11
+ end
12
+
13
+ # DP register write
14
+ if reg.owner == model
15
+ # Don't log this one, not really a DP reg and will be included
16
+ # in the JTAG driver log anyway
17
+ if reg.name == :ir
18
+ dut.jtag.write_ir(reg)
19
+ else
20
+
21
+ log "Write JTAG-DP register #{reg.name.to_s.upcase}: #{reg.data.to_hex}" do
22
+ if reg.name == :abort
23
+ ir.write!(reg.offset)
24
+ dr.reset
25
+ dr.overlay(nil)
26
+ dr[2..0].write(0)
27
+ dr[34..3].copy_all(reg)
28
+ dut.jtag.write_dr(dr)
29
+
30
+ # DPACC
31
+ elsif reg.name == :ctrlstat || reg.name == :select
32
+ dr.reset
33
+ dr.overlay(nil)
34
+ dr[0].write(0)
35
+ dr[2..1].write(reg.offset >> 2)
36
+ dr[34..3].copy_all(reg)
37
+ ir.write!(0b1010)
38
+ dut.jtag.write_dr(dr)
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!(0b1011)
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 == :ctrlstat || reg.name == :select || reg.name == :rdbuff
83
+
84
+ # Part 1 - Request read from DP-Register by writing to DPACC with RnW=1
85
+ dr.reset
86
+ dr.overlay(nil)
87
+ dr[0].write(1)
88
+ dr[2..1].write(reg.offset >> 2)
89
+ dr[34..3].write(0)
90
+ ir.write!(0b1010)
91
+ dut.jtag.write_dr(dr)
92
+
93
+ # Part 2 - Now read real data from RDBUFF (DP-Reg)
94
+ dr.reset
95
+ dr.overlay(nil)
96
+ dr[0].write(1)
97
+ dr[2..1].write(rdbuff.offset >> 2)
98
+ dr[34..3].copy_all(reg)
99
+ dut.jtag.read_dr(dr, options)
100
+
101
+ else
102
+ fail "Can't read #{reg.name}"
103
+ end
104
+ end
105
+ end
106
+
107
+ # AP register read
108
+ else
109
+ unless reg.owner.is_a?(AP)
110
+ fail 'The JTAG-DP can only write to DP or AP registers!'
111
+ end
112
+
113
+ # Part 1 - Request read from AP-Register by writing to APACC with RnW=1
114
+ select_ap_reg(reg)
115
+ dr.reset
116
+ dr.overlay(nil)
117
+ dr[0].write(1)
118
+ dr[2..1].write(reg.offset >> 2)
119
+ dr[34..3].write(0)
120
+ ir.write!(0b1011)
121
+ dut.jtag.write_dr(dr)
122
+
123
+ # Calling AP should provide any delay parameter for wait states between AP read request
124
+ # and when the data is available at the RDBUFF DP-Reg
125
+ if options[:apacc_wait_states]
126
+ options[:apacc_wait_states].cycles
127
+ end
128
+
129
+ # Part 2 - Now read real data from RDBUFF (DP-Reg)
130
+ dr.reset
131
+ dr.overlay(nil)
132
+ dr[0].write(1)
133
+ dr[2..1].write(rdbuff.offset >> 2)
134
+ dr[34..3].copy_all(reg)
135
+ ir.write!(0b1010)
136
+ dut.jtag.read_dr(dr, options)
137
+ end
138
+ end
139
+ end
140
+ end