origen_arm_debug 0.10.1 → 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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