1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#ifndef RPI_MMU_EXAMPLE_INTERRUPTS_H
#define RPI_MMU_EXAMPLE_INTERRUPTS_H
#include <stdint.h>
//offset of peripherals+ offset for first addresable register for interupt controller
#define RPI_INTERRUPT_CONTROLLER_BASE ( 0x3F000000UL + 0xB200 )
// Bits in the Enable_Basic_IRQs register to enable various interrupts.
// According to the BCM2835 ARM Peripherals manual, section 7.5 */
#define RPI_BASIC_ARM_TIMER_IRQ (1 << 0)
#define RPI_BASIC_ARM_MAILBOX_IRQ (1 << 1)
#define RPI_BASIC_ARM_DOORBELL_0_IRQ (1 << 2)
#define RPI_BASIC_ARM_DOORBELL_1_IRQ (1 << 3)
#define RPI_BASIC_GPU_0_HALTED_IRQ (1 << 4)
#define RPI_BASIC_GPU_1_HALTED_IRQ (1 << 5)
#define RPI_BASIC_ACCESS_ERROR_1_IRQ (1 << 6)
#define RPI_BASIC_ACCESS_ERROR_0_IRQ (1 << 7)
// @brief The interrupt controller memory mapped register set
typedef struct {
volatile uint32_t IRQ_basic_pending;
volatile uint32_t IRQ_pending_1;
volatile uint32_t IRQ_pending_2;
volatile uint32_t FIQ_control;
volatile uint32_t Enable_IRQs_1;
volatile uint32_t Enable_IRQs_2;
volatile uint32_t Enable_Basic_IRQs;
volatile uint32_t Disable_IRQs_1;
volatile uint32_t Disable_IRQs_2;
volatile uint32_t Disable_Basic_IRQs;
} rpi_irq_controller_t;
extern rpi_irq_controller_t* RPI_GetIrqController(void);
//TIMER
/*--------------------------------------------------------------------------}
{ LOCAL TIMER INTERRUPT ROUTING REGISTER - QA7_rev3.4.pdf page 18 }
{--------------------------------------------------------------------------*/
typedef union
{
struct
{
enum {
LOCALTIMER_TO_CORE0_IRQ = 0,
LOCALTIMER_TO_CORE1_IRQ = 1,
LOCALTIMER_TO_CORE2_IRQ = 2,
LOCALTIMER_TO_CORE3_IRQ = 3,
LOCALTIMER_TO_CORE0_FIQ = 4,
LOCALTIMER_TO_CORE1_FIQ = 5,
LOCALTIMER_TO_CORE2_FIQ = 6,
LOCALTIMER_TO_CORE3_FIQ = 7,
} Routing: 3; // @0-2 Local Timer routing
unsigned unused : 29; // @3-31
};
uint32_t Raw32; // Union to access all 32 bits as a uint32_t
} local_timer_int_route_reg_t;
/*--------------------------------------------------------------------------}
{ LOCAL TIMER CONTROL AND STATUS REGISTER - QA7_rev3.4.pdf page 17 }
{--------------------------------------------------------------------------*/
typedef union
{
struct
{
unsigned ReloadValue : 28; // @0-27 Reload value
unsigned TimerEnable : 1; // @28 Timer enable (1 = enabled)
unsigned IntEnable : 1; // @29 Interrupt enable (1= enabled)
unsigned unused : 1; // @30 Unused
unsigned IntPending : 1; // @31 Timer Interrupt flag (Read-Only)
};
uint32_t Raw32; // Union to access all 32 bits as a uint32_t
} local_timer_ctrl_status_reg_t;
/*--------------------------------------------------------------------------}
{ LOCAL TIMER CLEAR AND RELOAD REGISTER - QA7_rev3.4.pdf page 18 }
{--------------------------------------------------------------------------*/
typedef union
{
struct
{
unsigned unused : 30; // @0-29 unused
unsigned Reload : 1; // @30 Local timer-reloaded when written as 1
unsigned IntClear : 1; // @31 Interrupt flag clear when written as 1
};
uint32_t Raw32; // Union to access all 32 bits as a uint32_t
} local_timer_clr_reload_reg_t;
/*--------------------------------------------------------------------------}
{ GENERIC TIMER INTERRUPT CONTROL REGISTER - QA7_rev3.4.pdf page 13 }
{--------------------------------------------------------------------------*/
typedef union
{
struct
{
unsigned nCNTPSIRQ_IRQ : 1; // @0 Secure physical timer event IRQ enabled, This bit is only valid if bit 4 is clear otherwise it is ignored.
unsigned nCNTPNSIRQ_IRQ : 1; // @1 Non-secure physical timer event IRQ enabled, This bit is only valid if bit 5 is clear otherwise it is ignored
unsigned nCNTHPIRQ_IRQ : 1; // @2 Hypervisor physical timer event IRQ enabled, This bit is only valid if bit 6 is clear otherwise it is ignored
unsigned nCNTVIRQ_IRQ : 1; // @3 Virtual physical timer event IRQ enabled, This bit is only valid if bit 7 is clear otherwise it is ignored
unsigned nCNTPSIRQ_FIQ : 1; // @4 Secure physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (0)
unsigned nCNTPNSIRQ_FIQ : 1; // @5 Non-secure physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (1)
unsigned nCNTHPIRQ_FIQ : 1; // @6 Hypervisor physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (2)
unsigned nCNTVIRQ_FIQ : 1; // @7 Virtual physical timer event FIQ enabled, If set, this bit overrides the IRQ bit (3)
unsigned reserved : 24; // @8-31 reserved
};
uint32_t Raw32; // Union to access all 32 bits as a uint32_t
} generic_timer_int_ctrl_reg_t;
struct __attribute__((__packed__, aligned(4))) QA7Registers {
local_timer_int_route_reg_t TimerRouting; // 0x24
uint32_t GPIORouting; // 0x28
uint32_t AXIOutstandingCounters; // 0x2C
uint32_t AXIOutstandingIrq; // 0x30
local_timer_ctrl_status_reg_t TimerControlStatus; // 0x34
local_timer_clr_reload_reg_t TimerClearReload; // 0x38
uint32_t unused; // 0x3C
generic_timer_int_ctrl_reg_t Core0TimerIntControl; // 0x40
generic_timer_int_ctrl_reg_t Core1TimerIntControl; // 0x44
generic_timer_int_ctrl_reg_t Core2TimerIntControl; // 0x48
generic_timer_int_ctrl_reg_t Core3TimerIntControl; // 0x4C
};
#define QA7 ((volatile __attribute__((aligned(4))) struct QA7Registers*)(uintptr_t)(0x40000024))
//40000040
int enable_timer(void);
#endif //RPI_MMU_EXAMPLE_INTERRUPTS_H
|