origen_arm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,121 @@
1
+ module OrigenARM
2
+ module Cores
3
+ module CortexM
4
+ class Base
5
+ # The CortexM base registers. Ideally, everything here will be applicable
6
+ # to all Cortex M-Series cores.
7
+ # @note The information referenced in this file was taken from the readily-available
8
+ # online ARM documentation and is included here as a resource for developers.
9
+ # See http://infocenter.arm.com/help/index.jsp for the original source.
10
+ # This source can also be downloaded from https://developer.arm.com/ and selecting
11
+ # 'technical support' (login required).
12
+ module Registers
13
+ # Instantiates the CortexM base registers.
14
+ # These registers should be applicable to all CortexM cores.
15
+ #
16
+ # @note This is purposefully a class method to avoid overwriting
17
+ # the core's own <code>#inititalize_registers</code> method.
18
+ # @note <b>Extension Note:</b> The registers instantiated here can be post-processed
19
+ # if there are slight differences from core to core, rather than adding options here,
20
+ # reimplementing the method, or skipping the method entirely.
21
+ def self.instantiate_registers(dut, options = {})
22
+ # Any common registers can go here
23
+ instantiate_core_registers(dut, options)
24
+ end
25
+
26
+ # Instantiates general purpose core registers. These are mostly stable
27
+ # across all cortexM devices. Larger difference come into play on
28
+ # implementation details (e.g., does the core license include the FPU?)
29
+ #
30
+ # @todo This is only a subset of the core registers. Need to add the remaining as they're needed.
31
+ # @note None of these registers are directly accessible. These registers must go through the
32
+ # <code>DCRDR</code> and <code>DCRSR</code> registers with the <code>regsel</code> set appropriately.
33
+ # @note The base address of these registers correspond to the of <code>regsel</code> value needed to access
34
+ # this register.
35
+ def self.instantiate_core_registers(dut, options = {})
36
+ dut.add_reg(:reg0, 0x0, size: 32, description: 'General Purpose Register 0')
37
+ dut.add_reg(:reg1, 0x1, size: 32, description: 'General Purpose Register 1')
38
+ dut.add_reg(:reg2, 0x2, size: 32, description: 'General Purpose Register 2')
39
+ dut.add_reg(:reg3, 0x3, size: 32, description: 'General Purpose Register 3')
40
+ dut.add_reg(:reg4, 0x4, size: 32, description: 'General Purpose Register 4')
41
+ dut.add_reg(:reg5, 0x5, size: 32, description: 'General Purpose Register 5')
42
+ dut.add_reg(:reg6, 0x6, size: 32, description: 'General Purpose Register 6')
43
+ dut.add_reg(:reg7, 0x7, size: 32, description: 'General Purpose Register 7')
44
+
45
+ dut.reg(:reg0).meta[:general_purpose_register] = true
46
+ dut.reg(:reg1).meta[:general_purpose_register] = true
47
+ dut.reg(:reg2).meta[:general_purpose_register] = true
48
+ dut.reg(:reg3).meta[:general_purpose_register] = true
49
+ dut.reg(:reg4).meta[:general_purpose_register] = true
50
+ dut.reg(:reg5).meta[:general_purpose_register] = true
51
+ dut.reg(:reg6).meta[:general_purpose_register] = true
52
+ dut.reg(:reg7).meta[:general_purpose_register] = true
53
+
54
+ # Current Stack Pointer
55
+ dut.add_reg(:sp, 0xD, size: 32, description:
56
+ [
57
+ 'The Current Stack Pointer.',
58
+ 'The exact stack pointer this points to will change in the hardware depending on the mode, security, etc.',
59
+ 'This will, however, always point to the current stack pointer in use.'
60
+ ].join("\n")
61
+ )
62
+ dut.reg(:sp).meta[:special_purpose_register] = true
63
+
64
+ # Link Register
65
+ dut.add_reg(:lr, 0xE, size: 32, description: 'The Current Linker Register')
66
+ dut.reg(:lr).meta[:special_purpose_register] = true
67
+
68
+ # Debug Return Address (Return PC)
69
+ dut.add_reg(:debug_return_address, 0xF, size: 32, description:
70
+ 'Indicates the new program counter to be loaded after a successful vector catch occurs'
71
+ )
72
+ dut.reg(:debug_return_address).meta[:special_purpose_register] = true
73
+
74
+ # XPSR
75
+ # Note: This register also seems mostly stable across the entire
76
+ # CortexM family, but may need to be revisited as more cores are added.
77
+ dut.add_reg(:xpsr, 0x0, size: 32, description: 'Combined Program Status Register. Combination of APSR, EPSR, and IPSR Registers on Other ARM Cores.') do |r|
78
+ r.bits 31, :n, description: 'Negative flag. Reads or writes the current value of APSR.N.'
79
+ r.bits 30, :z, description: 'Zero flag. Reads or writes the current value of APSR.Z.'
80
+ r.bits 29, :c, description: 'Carry flag. Reads or writes the current value of APSR.C.'
81
+ r.bits 28, :v, description: 'Overflow flag. Reads or writes the current value of APSR.V.'
82
+ r.bits 27, :q, description: 'Saturate flag. Reads or writes the current value of APSR.Q.'
83
+ r.bits 26..25, :upper_it_ici, description:
84
+ [
85
+ 'Note: this register is split between this field and the :lower_it_ici bits',
86
+
87
+ 'When XPSR[:exception][11:10] != 0:',
88
+ ' Function as IT -> If-then Flags:',
89
+ ' If-then flags. Reads or writes the current value of EPSR.IT.',
90
+
91
+ 'When XPSR[:exception][11:10] == 0:',
92
+ ' Function as ICI -> Interrupt Continuation Flags:',
93
+ ' Interrupt continuation flags. Reads or writes the current value of EPSR.ICI.'
94
+ ].join("\n")
95
+ r.bits 24, :t, description: 'T32 state. Reads or writes the current value of EPSR.T.'
96
+ r.bits 23..20, :reserved, reset: 0
97
+ r.bits 19..16, :ge, description: 'Greater-than or equal flag. Reads or writes the current value of APSR.GE.'
98
+ r.bits 15..10, :lower_it_ici, description:
99
+ [
100
+ 'Note: this register is split between this field and the :upper_it_ici bits',
101
+
102
+ 'When XPSR[:exception][11:10] != 0:',
103
+ ' Function as IT -> If-then Flags:',
104
+ ' If-then flags. Reads or writes the current value of EPSR.IT.',
105
+
106
+ 'When XPSR[:exception][11:10] == 0:',
107
+ ' Function as ICI -> Interrupt Continuation Flags:',
108
+ ' Interrupt continuation flags. Reads or writes the current value of EPSR.ICI.'
109
+ ].join("\n")
110
+ r.bits 9, :reserved, reset: 0
111
+ r.bits 8..0, :exception, description: 'Exception number. Reads or writes the current value of IPSR.Exception.'
112
+ end
113
+ dut.reg(:xpsr).meta[:special_purpose_register] = true
114
+ end
115
+
116
+ # Any other common methods regarding registers can go here.
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'cm33_controller'
2
+
3
+ module OrigenARM
4
+ module Cores
5
+ module CortexM
6
+ class CM33 < OrigenARM::Cores::CortexM::Base
7
+ require_relative 'cm33_registers'
8
+ include Registers
9
+
10
+ def initialize(options = {})
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,96 @@
1
+ module OrigenARM
2
+ module Cores
3
+ module CortexM
4
+ class CM33Controller < OrigenARM::Cores::CortexM::BaseController
5
+ def initialize(options = {})
6
+ super
7
+ end
8
+
9
+ # Initializes the core, specifically geared towards LRE setup.
10
+ # @param pc [Fixnum] The absolute address to load into the program counter.
11
+ # @param sp [Fixnum] The absolute address to load into the current stack pointer.
12
+ # @param release_core [TrueClass, FalseClass] The core will need to be held in order to initialize. However, this parameter
13
+ # can indicate whether or not the core should be released following the setup.
14
+ # @param sp_lower_limit [Fixnum] Sets stack pointer's lower limit.
15
+ # @param sp_upper_limit [Fixnum] Sets stack pointer's upper limit.
16
+ # @todo Implement lower and upper stack pointer limit setting.
17
+ def initialize_core(pc:, sp:, release_core: false, sp_lower_limit: nil, sp_upper_limit: nil)
18
+ enter_debug_mode
19
+ set_sp(sp)
20
+ set_pc(pc)
21
+ # set_stack_limits(sp_lower_limit, sp_upper_limit) if (sp_lower_limit || sp_upper_limit)
22
+ exit_debug_mode(release_core: release_core)
23
+ end
24
+ alias_method :initialize_for_lre, :initialize_core
25
+
26
+ # Enters the core's debug mode.
27
+ # @param halt_core [true, false] Indicates whether the core should be held when entering debug mode.
28
+ # Some functionality may not work correctly if the core is not halted,
29
+ # but a halted core is not a requirement for debug mode.
30
+ def enter_debug_mode(halt_core: true)
31
+ pp('Entering Debug Mode...') do
32
+ reg(:dhcsr).bits(:dbgkey).write(OrigenARM::Cores::CortexM::CM33::Registers::DHCSR_DBGKEY)
33
+ reg(:dhcsr).bits(:c_debugen).write(1)
34
+ reg(:dhcsr).write!
35
+
36
+ enter_debug_mode_delay!
37
+
38
+ if halt_core
39
+ reg(:dhcsr).bits(:dbgkey).write(OrigenARM::Cores::CortexM::CM33::Registers::DHCSR_DBGKEY)
40
+ reg(:dhcsr).bits(:c_debugen).write(1)
41
+ reg(:dhcsr).bits(:c_halt).write(1)
42
+ reg(:dhcsr).write!
43
+ enter_debug_mode_delay!
44
+ end
45
+ end
46
+ end
47
+
48
+ # Exits the core's debug mode.
49
+ # @param release_core [true, false] Indicates whether the core should be held upon exiting debug mode.
50
+ def exit_debug_mode(release_core: true)
51
+ pp('Exiting Debug Mode...') do
52
+ reg(:dhcsr).bits(:dbgkey).write(OrigenARM::Cores::CortexM::CM33::Registers::DHCSR_DBGKEY)
53
+ reg(:dhcsr).bits(:c_halt).write(0) if release_core
54
+ reg(:dhcsr).bits(:c_debugen).write(0)
55
+ reg(:dhcsr).write!
56
+
57
+ cc 'Delay for the core to exit debug mode'
58
+ exit_debug_mode_delay!
59
+ end
60
+ end
61
+
62
+ # Sets the current stack pointer.
63
+ # @param sp [Fixnum] The new stack pointer.
64
+ # @note This sets the <b>current</b> stack pointer. The stack pointer in question
65
+ # depends on the core's/device's mode and security settings.
66
+ # @note This requires the core to be in debug mode, otherwise a bus error will occur.
67
+ def set_sp(sp)
68
+ pp('Patch the Stack Pointer') do
69
+ reg(:sp).write!(sp)
70
+ end
71
+ end
72
+
73
+ # Sets the program counter by writing the <code>debug_return_address</code> register.
74
+ # The <code>debug_return_address</code> will be loaded into the PC following
75
+ # debug mode exit, effectively moving the PC.
76
+ # @param pc [Fixnum] The new program counter (debug return address).
77
+ # @note This requires the core to be in debug mode, otherwise a bus error will occur.
78
+ # @note This method will also force <code>Thumb</code> mode.
79
+ def set_pc(pc)
80
+ pp('Patch the Program Counter') do
81
+ # Force the thumb bit. Nothing will work otherwise as CM33 only support THUMB
82
+ reg(:xpsr).bits(:t).write(1)
83
+ reg(:xpsr).write!
84
+
85
+ # Write the debug return address with the new PC
86
+ # Add 1 to indicate thumb mode
87
+ reg(:debug_return_address).write!(pc + 1)
88
+ end
89
+ end
90
+
91
+ # def set_stack_limits(lower_limit, upper_limits, stack: :msp, **options)
92
+ # end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,427 @@
1
+ # The information referenced in this file was taken from the readily-available
2
+ # online ARM documentation and is included here as a resource for developers.
3
+ # See http://infocenter.arm.com/help/index.jsp for the original source.
4
+ # This source can also be downloaded from https://developer.arm.com/ and selecting
5
+ # 'technical support' (login required).
6
+
7
+ module OrigenARM
8
+ module Cores
9
+ module CortexM
10
+ class CM33
11
+ module Registers
12
+ AIRCR_READ_KEY = 0xFA05
13
+ AIRCR_WRITE_KEY = 0x05FA
14
+ DHCSR_DBGKEY = 0xA05F
15
+
16
+ def instantiate_registers(options = {})
17
+ add_reg(:aircr, 0xE000_ED0C, size: 32, description: 'Application Interrupt and Reset Control Register') do |r|
18
+ r.bit 31..16, :vectkey, description: 'Vector key. Writes to the AIRCR must be accompanied by a write of the value 0x05FA to this field. Writes to the AIRCR fields that are not accompanied by this value are ignored for the purpose of dating any of the AIRCR values or initiating any AIRCR functionality.'
19
+ r.bit 15, :endianness, description: 'Data endianness. Indicates how the PE interprets the memory system data endianness. 0 -> Little-endian, 1 -> Big-endian.'
20
+ r.bit 14, :pris, description: 'Prioritize Secure exceptions. The value of this bit defines whether Secure exception priority boosting is enabled. 0 -> Priority ranges of Secure and Non-secure exceptions are identical, 1 -> Non-secure exceptions are de-prioritized.'
21
+ r.bit 13, :bfhfnmins, description: 'BusFault, HardFault, and NMI Non-secure enable. The value of this bit defines whether BusFault and NMI exceptions are Non-secure, and whether exceptions target the Non-secure HardFault exception. 0 -> BusFault, HardFault, and NMI are Secure, 1 -> BusFault and NMI are Non-secure and exceptions can target Non-secure HardFault.'
22
+ r.bit 12..11, :reserved
23
+ r.bit 10..8, :prigroup, description: 'Priority grouping. The value of this field defines the exception priority binary point position for the selected Security state.'
24
+ r.bit 7..4, :reserved
25
+ r.bit 3, :sysresetreqs, description: 'System reset request Secure only. The value of this bit defines whether the SYSRESETREQ bit is functional for Non-secure use. 0 -> SYSRESETREQ functionality is available to both Security states, 1 -> SYSRESETREQ functionality is only available to Secure state.'
26
+ r.bit 2, :sysresetreq, description: 'System reset request. This bit allows software or a debugger to request a system reset. 0 -> Do not request a system reset., 1 -> Request a system reset.'
27
+ r.bit 1, :vectclractive, description: 'Clear active state. A debugger write of one to this bit when the PE is halted in Debug state. 0 -> Do nothing, 1 -> Clear active state (IPSR is cleared to zero, The active state for all Non-secure exceptions is cleared, If DHCSR.S_SDE==1, the active state for all Secure exceptions is cleared).'
28
+ r.bit 0, :reserved
29
+ end
30
+
31
+ add_reg(:dhcsr, 0xE000_EDF0, size: 32, description: 'Debug Halting Control and Status Register') do |r|
32
+ r.bit 31..16, :dbgkey, description: 'Debug key. A debugger must write 0xA05F to this field to enable write access to the remaining bits, otherwise the PE ignores the write access.'
33
+ r.bit 15..6, :reserved
34
+ r.bit 5, :c_snapstall, description:
35
+ [
36
+ 'Snap stall control.',
37
+ 'Setting this bit to 1 allows a debugger to request an imprecise entry to Debug state. Writing 1 to this makes the state of the memory system UNPREDICTABLE. Therefore if a debugger writes 1 to this bit it must reset the system before leaving Debug state.', 'Allow imprecise entry to Debug state.',
38
+ 'The effect of setting this bit to 1 is UNPREDICTABLE unless the DHCSR write also sets C_DEBUGEN and C_HALT to 1. This means that if the PE is not already in Debug state, it enters Debug state when the stalled instruction completes.',
39
+ 'If the Security Extension is implemented, then writes to this bit are ignored when DHCSR.S_SDE == 0.',
40
+ 'If DHCSR.C_DEBUGEN == 0 or HaltingDebugAllowed() == FALSE, the PE ignores this bit and behaves as if it is set to 0.',
41
+ 'If the Main Extension is not implemented, this bit is RES0.',
42
+ '0 -> No action.',
43
+ '1 -> Allows imprecise entry to Debug state, for example by forcing any stalled load or store instruction to be abandoned.'
44
+ ].join("\n")
45
+ r.bit 4, :reserved
46
+ r.bit 3, :c_maskints, description:
47
+ [
48
+ 'Mask interrupts control. When debug is enabled, the debugger can write to this bit to mask PendSV, SysTick and external configurable interrupts.',
49
+ 'The effect of any single write to DHCSR that changes the value of this bit is UNPREDICTABLE unless one of:',
50
+ 'Before the write, DHCSR.{S_HALT,C_HALT} are both set to 1 and the write also writes 1 to DHCSR.C_HALT.',
51
+ 'Before the write, DHCSR.C_DEBUGEN == 0 or HaltingDebugAllowed() == FALSE, and the write writes 0 to DHCSR.C_MASKINTS. This means that a single write to DHCSR must not clear DHCSR.C_HALT to 0 and change the value of the C_MASKINTS bit.',
52
+ 'If the Security Extension is implemented and DHCSR.S_SDE == 0, this bit does not affect
53
+ interrupts targeting Secure state.',
54
+ 'If DHCSR.C_DEBUGEN == 0 or HaltingDebugAllowed() == FALSE, the PE ignores this bit and behaves as if it is set to 0.',
55
+ 'If DHCSR.C_DEBUGEN == 0 this but reads as an UNKNOWN value.',
56
+ 'This bit resets to an UNKNOWN value on a Cold reset.',
57
+ '0 -> Do not mask.',
58
+ '1 -> Mask PendSV, SysTick and external configurable interrupts.'
59
+ ].join("\n")
60
+ r.bit 2, :c_step, reset: 0, description:
61
+ [
62
+ 'Step control. Enable single instruction step.',
63
+ 'The effect of a single write to DHCSR that changes the value of this bit is UNPREDICTABLE unless one of:',
64
+ 'Before the write, DHCSR.{S_HALT,C_HALT} are both set to 1.',
65
+ 'Before the write, DHCSR.C_DEBUGEN == 0 or HaltingDebugAllowed() == FALSE, and the write writes 0 to DHCSR.C_STEP.',
66
+ 'The PE ignores this bit and behaves as if it set to 0 if any of:',
67
+ 'DHCSR.C_DEBUGEN == 0 or HaltingDebugAllowed() == FALSE.',
68
+ 'The Security Extension is implemented, DHCSR.S_SDE == 0 and the PE is in Secure state.',
69
+ 'If DHCSR.C_DEBUGEN == 0 this bit reads as an UNKNOWN',
70
+ '0 -> No effect.',
71
+ '1 -> Single step enabled.'
72
+ ].join("\n")
73
+ r.bit 1, :c_halt, reset: 0, description:
74
+ [
75
+ 'Halt control. PE to enter Debug state halt request.',
76
+ 'The PE sets C_HALT to 1 when a debug event pends an entry to Debug state.',
77
+ 'The PE ignores this bit and behaves as if it is set to 0 if any of:',
78
+ 'DHCSR.C_DEBUGEN == 0 or HaltingDebugAllowed() == FALSE.',
79
+ 'The Security Extension is implemented, DHCSR.S_SDE == 0 and the PE is in Secure state.',
80
+ 'If DHCSR.C_DEBUGEN == 0 this bit reads as an UNKNOWN value.',
81
+ 'This bit resets to zero on a Warm reset.',
82
+ '0 -> Causes the PE to leave Debug state, if in Debug state.',
83
+ '1 -> Halt the PE.'
84
+ ].join("\n")
85
+ r.bit 0, :c_debugen, reset: 0, description:
86
+ [
87
+ 'Debug enable control. Enable Halting debug.',
88
+ 'The possible values of this bit are:',
89
+ 'If a debugger writes to DHCSR to change the value of this bit from 0 to 1, it must also write 0 to the C_MASKINTS bit, otherwise behavior is UNPREDICTABLE.',
90
+ 'If this bit is set to 0:',
91
+ 'The PE behaves as if DHCSR.{C_MASKINTS, C_STEP, C_HALT} are all set to 0.',
92
+ 'DHCSR.{S_RESTART_ST, C_MASKINTS, C_STEP, C_HALT} are UNKNOWN on reads of DHCSR.',
93
+ 'This bit is read/write to the debugger. Writes from software are ignored.',
94
+ 'This bit resets to zero on a Cold reset.',
95
+ '0 -> Disabled.',
96
+ '1 -> Enabled.'
97
+ ].join("\n")
98
+ end
99
+
100
+ add_reg(:dcrsr, 0xE000_EDF4, size: 32, description: 'Debug Core Register Select Register') do |r|
101
+ r.bit 31..17, :reserved
102
+ r.bit 16, :regwnr, description:
103
+ [
104
+ 'Register write/not-read. Specifies the access type for the transfer.',
105
+ '0 -> Read.',
106
+ '1 -> Write.'
107
+ ].join("\n")
108
+ r.bit 15..7, :reserved
109
+ # Register definition from the reference manual:
110
+ # Register selector. Specifies the general-purpose register, special-purpose register, or Floating-point
111
+ # Extension register to transfer.
112
+ # The possible values of this field are:
113
+ # 0b0000000-0b0001100
114
+ # General-purpose registers R0-R12.
115
+ # 0b0001101 Current stack pointer, SP.
116
+ # 0b0001110 LR.
117
+ # 0b0001111 DebugReturnAddress.
118
+ # 0b0010000 XPSR.
119
+ # 0b0010001 Current state main stack pointer, SP_main.
120
+ # 0b0010010 Current state process stack pointer, SP_process.
121
+ # 0b0010100 Current state {CONTROL[7:0],FAULTMASK[7:0],BASEPRI[7:0],PRIMASK[7:0]}.
122
+ # If the Main Extension is not implemented, bits [23:8] of the transfer value are RES0.
123
+ # 0b0011000 Non-secure main stack pointer, MSP_NS.
124
+ # If the Security Extension is not implemented, this value is reserved.
125
+ # 0b0011001 Non-secure process stack pointer, PSP_NS.
126
+ # If the Security Extension is not implemented, this value is reserved.
127
+ # 0b0011010 Secure main stack pointer, MSP_S. Accessible only when DHCSR.S_SDE == 1.
128
+ # If the Security Extension is not implemented, this value is reserved.
129
+ # 0b0011011 Secure process stack pointer, PSP_S. Accessible only when DHCSR.S_SDE == 1.
130
+ # If the Security Extension is not implemented, this value is reserved.
131
+ # 0b0011100 Secure main stack limit, MSPLIM_S. Accessible only when DHCSR.S_SDE ==
132
+ # 0b0011101 Secure process stack limit, PSPLIM_S. Accessible only when DHCSR.S_SDE == 1.
133
+ # If the Security Extension is not implemented, this value is reserved.
134
+ # 0b0011110 Non-secure main stack limit, MSPLIM_NS.
135
+ # If the Main Extension is not implemented, this value is reserved.
136
+ # 0b0011111 Non-secure process stack limit, PSPLIM_NS.
137
+ # If the Main Extension is not implemented, this value is reserved.
138
+ # 0b0100001 FPSCR.
139
+ # If the Floating-point Extension is not implemented, this value is reserved.
140
+ # 0b0100010 {CONTROL_S[7:0],FAULTMASK_S[7:0],BASEPRI_S[7:0],PRIMASK_S[7:0]}.
141
+ # Accessible only when DHCSR.S_SDE == 1.
142
+ # If the Main Extension is not implemented, bits [23:8] of the transfer value are RES0. If
143
+ # the Security Extension is not implemented, this value is reserved.
144
+ # 0b0100011
145
+ # {CONTROL_NS[7:0],FAULTMASK_NS[7:0],BASEPRI_NS[7:0],PRIMASK_NS[7:
146
+ # 0]}.
147
+ # If the Main Extension is not implemented, bits [23:8] of the transfer value are RES0. If
148
+ # the Security Extension is not implemented, this value is reserved.
149
+ # 0b1000000-0b1011111
150
+ # FP registers, S0-S31.
151
+ # If the Floating-point Extension is not implemented, these values are reserved.
152
+ # All other values are reserved.
153
+ # If the Floating-point and Security Extensions are implemented, then FPSCR and S0-S31 are not
154
+ # accessible from Non-secure state if DHCSR.S_SDE == 0 and either:
155
+ # FPCCR indicates the registers contain values from Secure state.
156
+ # NSACR prevents Non-secure access to the registers.
157
+ # Registers that are not accessible are RAZ/WI.
158
+ # If this field is written with a reserved value, the PE might behave as if a defined value was written,
159
+ # or ignore the value written, and the value of DCRDR becomes UNKNOWN.
160
+ r.bit 6..0, :reg_sel, description:
161
+ [
162
+ 'Register selector.',
163
+ 'Specifies the general-purpose register, special-purpose register, or Floating-point Extension register to transfer.'
164
+ ].join("\n")
165
+ end
166
+
167
+ add_reg(:dcrdr, 0xE000_EDF8, size: 32, description: 'Debug Core Register Data Register') do |r|
168
+ r.bits 31..0, :dbgtmp, description:
169
+ [
170
+ 'Data temporary buffer. Provides debug access for reading and writing the general-purpose registers, ' \
171
+ 'special-purpose registers, and Floating-point Extension registers.',
172
+
173
+ 'The value of this register is UNKNOWN if the PE is in Debug state, the debugger has written to ' \
174
+ 'DCRSR since entering Debug state and DHCSR.S_REGRDY is set to 0. The value of this register ' \
175
+ 'is UNKNOWN if the Main Extension is not implemented and the PE is in Non-debug state.',
176
+
177
+ 'This field resets to an UNKNOWN value on a Warm reset.',
178
+ 'Any written contents will be overwritten on a successful core-register read attempt.'
179
+ ].join("\n")
180
+ end
181
+
182
+ add_reg(:demcr, 0xE000_EDFC, size: 32, description: 'Debug Exception and Monitor Control Register') do |r|
183
+ r.bits 31..25, :reserved
184
+ r.bits 24, :trcena, description:
185
+ [
186
+ 'Trace enable. Global enable for all DWT and ITM features.',
187
+
188
+ 'If the DWT and ITM units are not implemented, this bit is RES0. See the descriptions of DWT and ' \
189
+ 'ITM for details of which features this bit controls.',
190
+
191
+ 'Setting this bit to 0 might not stop all events. To ensure that all events are stopped, software must ' \
192
+ 'set all DWT and ITM feature enable bits to 0, and ensure that all trace generated by the DWT and ' \
193
+ 'ITM has been flushed, before setting this bit to 0.',
194
+
195
+ 'It is IMPLEMENTATION DEFINED whether this bit affects how the system processes trace. ' \
196
+ 'Arm recommends that this bit is set to 1 when using an ETM even if any implemented DWT and ' \
197
+ 'ITM are not being used.',
198
+
199
+ 'This bit resets to zero on a Cold reset.',
200
+
201
+ '0 -> DWT and ITM features disabled.',
202
+ '1 -> DWT and ITM features enabled.'
203
+ ].join("\n")
204
+ r.bits 23..21, :reserved
205
+ r.bits 20, :sdme, description:
206
+ [
207
+ 'Secure DebugMonitor enable. Indicates whether the DebugMonitor targets the Secure or the ' \
208
+ 'Non-secure state and whether debug events are allowed in Secure state.',
209
+
210
+ 'When DebugMonitor exception is not pending or active, this bit reflects the value of ' \
211
+ 'SecureDebugMonitorAllowed(), otherwise, the previous value is retained.',
212
+
213
+ 'This bit is read-only.',
214
+
215
+ 'If the Security Extension is not implemented, this bit is RES0. ' \
216
+ 'If the Main Extension is not implemented, this bit is RES0.',
217
+
218
+ '0 -> Debug events prohibited in Secure state and the DebugMonitor exception targets Non-secure state.',
219
+ '1 -> Debug events allowed in Secure state and the DebugMonitor exception targets Secure state.'
220
+ ].join("\n")
221
+ r.bits 19, :mon_req, description:
222
+ [
223
+ 'Monitor request. DebugMonitor semaphore bit.',
224
+
225
+ 'The PE does not use this bit. The monitor software defines the meaning and use of this bit.',
226
+
227
+ 'If the Main Extension is not implemented, this bit is RES0.',
228
+
229
+ 'This bit resets to zero on a Warm reset.'
230
+ ].join("\n")
231
+ r.bits 18, :mon_step, description:
232
+ [
233
+ 'Monitor step. Enable DebugMonitor exception stepping.',
234
+
235
+ 'The effect of changing this bit at an execution priority that is lower than the priority of the ' \
236
+ 'DebugMonitor exception is UNPREDICTABLE.',
237
+
238
+ 'If the Main Extension is not implemented, this bit is RES0.',
239
+
240
+ 'This bit resets to zero on a Warm reset.',
241
+
242
+ '0 -> Stepping disabled.',
243
+ '1 -> Stepping enabled.'
244
+ ].join("\n")
245
+ r.bits 17, :mon_pend, description:
246
+ [
247
+ 'Monitor pend. Sets or clears the pending state of the DebugMonitor exception.',
248
+
249
+ 'When the DebugMonitor exception is pending it becomes active subject to the exception priority ' \
250
+ 'rules. The effect of setting this bit to 1 is not affected by the value of the MON_EN bit. This means ' \
251
+ 'that software or a debugger can set MON_PEND to 1 and pend a DebugMonitor exception, even ' \
252
+ 'when MON_EN is set to 0.',
253
+
254
+ 'If the Main Extension is not implemented, this bit is RES0.',
255
+
256
+ 'This bit resets to zero on a Warm reset.',
257
+
258
+ '0 -> Clear the status of the DebugMonitor exception to not pending.',
259
+ '1 -> Set the status of the DebugMonitor exception to pending.'
260
+ ].join("\n")
261
+ r.bits 16, :mon_en, description:
262
+ [
263
+ 'Monitor enable. Enable the DebugMonitor exception.',
264
+
265
+ 'If a debug event halts the PE, the PE ignores the value of this bit.',
266
+ 'If DEMCR.SDME is one this bit is RAZ/WI from Non-secure state',
267
+
268
+ 'If the Main Extension is not implemented, this bit is RES0.',
269
+
270
+ 'This bit resets to zero on a Warm reset.',
271
+
272
+ '0 -> DebugMonitor exception disabled.',
273
+ '1 -> DebugMonitor exception enabled.'
274
+ ].join("\n")
275
+ r.bits 15..12, :reserved
276
+ r.bits 11, :vc_sferr, description:
277
+ [
278
+ 'Vector Catch SecureFault. SecureFault exception Halting debug vector catch enable.',
279
+
280
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
281
+ 'FALSE, or DHCSR.S_SDE == 0.',
282
+
283
+ 'If the Security Extension is not implemented, this bit is RES0.',
284
+ 'If the Main Extension is not implemented, this bit is RES0.',
285
+ 'If Halting debug is not implemented, this bit is RES0.',
286
+
287
+ 'This bit resets to zero on a Cold reset.',
288
+
289
+ '0 -> Halting debug trap on SecureFault disabled.',
290
+ '1 -> Halting debug trap on SecureFault enabled.'
291
+ ].join("\n")
292
+ r.bits 10, :vc_harderr, description:
293
+ [
294
+ 'Vector Catch HardFault errors. HardFault exception Halting debug vector catch enable.',
295
+
296
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
297
+ 'FALSE, or the Security Extension is implemented, DHCSR.S_SDE == 0 and the exception targets ' \
298
+ 'Secure state.',
299
+
300
+ 'If Halting debug is not implemented, this bit is RES0.',
301
+
302
+ 'This bit resets to zero on a Cold reset.',
303
+
304
+ '0 -> Halting debug trap on HardFault disabled.',
305
+ '1 -> Halting debug trap on HardFault enabled.'
306
+ ].join("\n")
307
+ r.bits 9, :vc_interr, description:
308
+ [
309
+ 'Vector Catch interrupt errors. Enable Halting debug vector catch for faults arising in lazy state ' \
310
+ 'preservation and during exception entry or return.',
311
+
312
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
313
+ 'FALSE, or the Security Extension is implemented, DHCSR.S_SDE == 0 and the exception targets Secure state.',
314
+
315
+ 'If the Main Extension is not implemented, this bit is RES0.',
316
+ 'If Halting debug is not implemented, this bit is RES0.',
317
+
318
+ 'This bit resets to zero on a Cold reset.',
319
+
320
+ '0 -> Halting debug trap on faults disabled.',
321
+ '1 -> Halting debug trap on faults enabled.'
322
+ ].join("\n")
323
+ r.bits 8, :vc_buserr, description:
324
+ [
325
+ 'Vector Catch BusFault errors. BusFault exception Halting debug vector catch enable.',
326
+
327
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
328
+ 'FALSE, or the Security Extension is implemented, DHCSR.S_SDE == 0 and the exception targets ' \
329
+ 'Secure state.',
330
+
331
+ 'If the Main Extension is not implemented, this bit is RES0.',
332
+ 'If Halting debug is not implemented, this bit is RES0.',
333
+
334
+ 'This bit resets to zero on a Cold reset.',
335
+
336
+ '0 -> Halting debug trap on BusFault disabled.',
337
+ '1 -> Halting debug trap on BusFault enabled.'
338
+ ].join("\n")
339
+ r.bits 7, :vc_staterr, description:
340
+ [
341
+ 'Vector Catch state errors. Enable Halting debug trap on a UsageFault exception caused by a state ' \
342
+ 'information error, for example an Undefined Instruction exception.',
343
+
344
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
345
+ 'FALSE, or the Security Extension is implemented, DHCSR.S_SDE == 0 and the exception targets ' \
346
+ 'Secure state.',
347
+
348
+ 'If the Main Extension is not implemented, this bit is RES0.',
349
+ 'If Halting debug is not implemented, this bit is RES0.',
350
+
351
+ 'This bit resets to zero on a Cold reset.',
352
+
353
+ '0 -> Halting debug trap on UsageFault caused by state information error disabled.',
354
+ '1 -> Halting debug trap on UsageFault caused by state information error enabled.'
355
+ ].join("\n")
356
+ r.bits 6, :vc_chkerr, description:
357
+ [
358
+ 'Vector Catch check errors. Enable Halting debug trap on a UsageFault exception caused by a ' \
359
+ 'checking error, for example an alignment check error.',
360
+
361
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
362
+ 'FALSE, or the Security Extension is implemented, DHCSR.S_SDE == 0 and the exception targets ' \
363
+ 'Secure state.',
364
+
365
+ 'If the Main Extension is not implemented, this bit is RES0.',
366
+ 'If Halting debug is not implemented, this bit is RES0.',
367
+
368
+ 'This bit resets to zero on a Cold reset.',
369
+
370
+ '0 -> Halting debug trap on UsageFault caused by checking error disabled.',
371
+ '1 -> Halting debug trap on UsageFault caused by checking error enabled.'
372
+ ].join("\n")
373
+ r.bits 5, :vc_nocperr, description:
374
+ [
375
+ 'Vector Catch NOCP errors. Enable Halting debug trap on a UsageFault caused by an access to a coprocessor.',
376
+
377
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
378
+ 'FALSE, or the Security Extension is implemented, DHCSR.S_SDE == 0 and the exception targets ' \
379
+ 'Secure state.',
380
+
381
+ 'If the Main Extension is not implemented, this bit is RES0.',
382
+ 'If Halting debug is not implemented, this bit is RES0.',
383
+
384
+ 'This bit resets to zero on a Cold reset.',
385
+
386
+ '0 -> Halting debug trap on UsageFault caused by access to a coprocessor disabled.',
387
+ '1 -> Halting debug trap on UsageFault caused by access to a coprocessor enabled.'
388
+ ].join("\n")
389
+ r.bits 4, :vc_mmerr, description:
390
+ [
391
+ 'Vector Catch MemManage errors. Enable Halting debug trap on a MemManage exception.',
392
+
393
+ 'The PE ignores the value of this bit if DHCSR.C_DEBUGEN == 0, HaltingDebugAllowed() == ' \
394
+ 'FALSE, or the Security Extension is implemented, DHCSR.S_SDE == 0 and the exception targets ' \
395
+ 'Secure state.',
396
+
397
+ 'If the Main Extension is not implemented, this bit is RES0.',
398
+ 'If Halting debug is not implemented, this bit is RES0.',
399
+
400
+ 'This bit resets to zero on a Cold reset.',
401
+
402
+ '0 -> Halting debug trap on MemManage disabled.',
403
+ '1 -> Halting debug trap on MemManage enabled.'
404
+ ].join("\n")
405
+ r.bits 3..1, :reserved
406
+ r.bits 0, :rv_corereset, description:
407
+ [
408
+ 'Vector Catch Core reset. Enable Reset Vector Catch. This causes a Warm reset to halt a running system.',
409
+
410
+ 'If DHCSR.C_DEBUGEN == 0 or HaltingDebugAllowed() == FALSE, the PE ignores the value of ' \
411
+ 'this bit. Otherwise, when this bit is set to 1 a Warm reset will pend a Vector Catch debug event. The ' \
412
+ 'debug event is pended even the PE resets into Secure state and DHCSR.S_SDE == 0.',
413
+
414
+ 'If Halting debug is not implemented, this bit is RES0.',
415
+
416
+ 'This bit resets to zero on a Cold reset.',
417
+
418
+ '0 -> Halting debug trap on reset disabled.',
419
+ '1 -> Halting debug trap on reset enabled.'
420
+ ].join("\n")
421
+ end
422
+ end
423
+ end
424
+ end
425
+ end
426
+ end
427
+ end