blob: e193dba64e5e0d4e56392e5903c3116d079de63d [file] [log] [blame]
Xiaohu.Huangbe565062021-10-15 17:29:19 +08001// See LICENSE for license details.
2#include <stdio.h>
3#include "common.h"
4#include "riscv_encoding.h"
5#include "interrupt_control.h"
6#include "register.h"
7#include "FreeRTOS.h"
8
9void pic_set_threshold(uint32_t threshold)
10{
11 volatile uint32_t* threshold_ptr = (uint32_t*) (PIC_CTRL_ADDR +
12 PIC_THRESHOLD_OFFSET);
13
14 *threshold_ptr = threshold;
15}
16
17void pic_enable_interrupt(uint32_t source)
18{
19 volatile uint32_t * current_ptr = (volatile uint32_t *)(PIC_CTRL_ADDR +
20 PIC_ENABLE_OFFSET +
21 ((source >> 3) & (~0x3))//Source number divide 32 and then multip 4 (bytes)
22 );
23 uint32_t current = *current_ptr;
24 current = current | ( 1 << (source & 0x1f));// Only check the least 5 bits
25 *current_ptr = current;
26}
27
28void pic_disable_interrupt (uint32_t source){
29
30 volatile uint32_t * current_ptr = (volatile uint32_t *) (PIC_CTRL_ADDR +
31 PIC_ENABLE_OFFSET +
32 ((source >> 3) & (~0x3))//Source number divide 32 and then multip 4 (bytes)
33 );
34 uint32_t current = *current_ptr;
35 current = current & ~(( 1 << (source & 0x1f)));// Only check the least 5 bits
36 *current_ptr = current;
37}
38
39void pic_set_priority (uint32_t source, uint32_t priority){
40
41 if (PIC_NUM_PRIORITIES > 0) {
42 volatile uint32_t * priority_ptr = (volatile uint32_t *)
43 (PIC_CTRL_ADDR +
44 PIC_PRIORITY_OFFSET +
45 (source << PIC_PRIORITY_SHIFT_PER_SOURCE));// Each priority reg occupy a word, so multiple 2
46 *priority_ptr = priority;
47 }
48}
49
50uint32_t pic_claim_interrupt(void){
51
52 volatile uint32_t * claim_addr = (volatile uint32_t * )
53 (PIC_CTRL_ADDR +
54 PIC_CLAIM_OFFSET
55 );
56
57 return *claim_addr;
58}
59
60uint32_t pic_check_eip(void){
61
62 volatile uint32_t * eip_addr = (volatile uint32_t * )
63 (PIC_CTRL_ADDR +
64 PIC_EIP_OFFSET
65 );
66
67 return *eip_addr;
68}
69
70void pic_complete_interrupt(uint32_t source){
71
72 volatile uint32_t * claim_addr = (volatile uint32_t *) (PIC_CTRL_ADDR +
73 PIC_CLAIM_OFFSET
74 );
75 *claim_addr = source;
76}
77
78void DefaultInterruptHandler(void)
79{
80}
81
82int RegisterIrq(uint32_t int_num, uint32_t int_priority, function_ptr_t handler) {
83 pic_interrupt_handlers[int_num] = handler;
84 pic_set_priority(int_num, int_priority);
85 // pic_enable_interrupt (int_num);
86 return 0;
87}
88
89int UnRegisterIrq(uint32_t int_num)
90{
91 pic_interrupt_handlers[int_num] = DefaultInterruptHandler;
92 pic_set_priority(int_num, 0);
93
94 return 0;
95}
96
97int EnableIrq(uint32_t ulIrq)
98{
99 UBaseType_t uxSavedInterruptStatus;
100
101 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
102 pic_enable_interrupt(ulIrq);
103 portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
104 return 0;
105}
106
107int DisableIrq(uint32_t ulIrq)
108{
109 UBaseType_t uxSavedInterruptStatus;
110
111 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
112 pic_disable_interrupt(ulIrq);
113 portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
114 return 0;
115}
116
117int SetIrqPriority(uint32_t ulIrq, uint32_t ulPri)
118{
119 pic_set_priority(ulIrq, ulPri);
120 return 0;
121}
122
123static unsigned int irq_setting[IRQ_EN_REG_NUM];
124/*N205 does not support clear pending irq.*
125 *Need use work around to clear pending: *
126 *1. disable irq (MIE) *
127 *2. store and disable current enable irq *
128 *3. enable target irq *
129 *4. claim and complete target irq *
130 *5. disable target irq *
131 *6. restore current irq enable setting *
132 *7. enable irq (MIE)
133*/
134int ClearPendingIrq(uint32_t ulIrq)
135{
136 unsigned int i;
137 volatile uint32_t * current_ptr;
138 unsigned long irq_status;
139
140 irq_status = interrupt_status_get();
141 if (irq_status)
142 interrupt_disable();
143
144 for (i = 0; i < IRQ_EN_REG_NUM; i++)
145 {
146 current_ptr =
147 (volatile uint32_t *)(PIC_CTRL_ADDR + PIC_ENABLE_OFFSET + i*4);
148 irq_setting[i] =
149 REG32(current_ptr);
150 REG32(current_ptr) = 0;
151 }
152 pic_enable_interrupt(ulIrq);
153 i = pic_claim_interrupt();
154 if (i)
155 pic_complete_interrupt(i);
156 pic_disable_interrupt(ulIrq);
157
158 for (i = 0; i < IRQ_EN_REG_NUM; i++)
159 {
160 current_ptr =
161 (volatile uint32_t *)(PIC_CTRL_ADDR + PIC_ENABLE_OFFSET + i*4);
162 REG32(current_ptr) = irq_setting[i];
163 }
164
165 if (irq_status)
166 interrupt_enable();
167
168 return 0;
169}
170