1 /* ------------------------------------------
2 * Copyright (c) 2016, Synopsys, Inc. All rights reserved.
3
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6
7 * 1) Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9
10 * 2) Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
13
14 * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may
15 * be used to endorse or promote products derived from this software without
16 * specific prior written permission.
17
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 --------------------------------------------- */
29
30 #include "arc.h"
31
32 /*********************************************************************
33 * Core Intc setup
34 *********************************************************************/
35
36 #define AUX_STAT32 0x00a
37
38 #define AUX_IVT_BASE 0x025
39 #define AUX_VOL 0x05e
40
41 #define AUX_IRQ_CTRL 0x00E
42 #define AUX_IRQ_SEL 0x40b
43 #define AUX_IRQ_PRIO 0x206
44
45 #define INTC_DEF_PRIO 1
46
47
48 /*********************************************************************
49 * Timers uses timer0
50 *********************************************************************/
51
52 #define AUX_TIM0_CNT 0x021
53 #define AUX_TIM0_CTRL 0x022
54 #define AUX_TIM0_LIMIT 0x023
55
56
57
58 /*********************************************************************
59 * Inter Core interruts
60 *********************************************************************/
61
62 #define AUX_MCIP_BCR 0x0d0
63 #define AUX_MCIP_CMD 0x600
64 #define AUX_MCIP_WDATA 0x601
65 #define AUX_MCIP_READBK 0x602
66
67 #define CMD_ICI_GENERATE_IRQ 0x1
68 #define CMD_ICI_GENERATE_ACK 0x2
69 #define CMD_ICI_READ_STATUS 0x3
70 #define CMD_ICI_CHECK_SOURCE 0x4
71
72
73
74 void _tx_thread_smp_initialize_wait(void);
75 void arc_timer_setup(unsigned int cycles);
76
77
arc_cpu_init(void)78 void arc_cpu_init(void)
79 {
80 extern char VECT_TABLE_BASE[]; // from sample_threadx.lcf
81 _sr((unsigned int)VECT_TABLE_BASE, AUX_IVT_BASE);
82
83 /* 0xc000_0000 in uncached */
84 _sr(0xc0000000, AUX_VOL);
85
86 /* setup irqs to interrupt at default interruption threshhold */
87 _sr(IRQ_TIMER, AUX_IRQ_SEL);
88 _sr(INTC_DEF_PRIO, AUX_IRQ_PRIO);
89
90 _sr(IRQ_IPI, AUX_IRQ_SEL);
91 _sr(INTC_DEF_PRIO, AUX_IRQ_PRIO);
92
93 #ifndef TX_ZERO_BASED_CORE_ID
94 if (smp_processor_id() > 1)
95 #else
96 if (smp_processor_id() > 0)
97 #endif
98 _tx_thread_smp_initialize_wait();
99
100 arc_timer_setup(19999);
101 }
102
103
arc_timer_setup(unsigned int cycles)104 void arc_timer_setup(unsigned int cycles)
105 {
106 _sr(cycles, AUX_TIM0_LIMIT); /* interupt after CNT == @cycles */
107 _sr(0, AUX_TIM0_CNT); /* initial CNT */
108 _sr(0x3, AUX_TIM0_CTRL); /* Interrupt enable, count only when NOT halted */
109 }
110
111
112
__mcip_cmd(unsigned int cmd,unsigned int param)113 static inline void __mcip_cmd(unsigned int cmd, unsigned int param)
114 {
115 struct mcip_cmd {
116 unsigned int cmd:8, param:16, pad:8;
117 } buf;
118
119 buf.pad = 0;
120 buf.cmd = cmd;
121 buf.param = param;
122
123 _sr(*(unsigned int *)&buf, AUX_MCIP_CMD);
124 }
125
126
arc_ici_send(unsigned int cpu)127 void arc_ici_send(unsigned int cpu)
128 {
129 int ipi_pend;
130
131 __mcip_cmd(CMD_ICI_READ_STATUS, cpu);
132 ipi_pend = _lr(AUX_MCIP_READBK);
133 if (!ipi_pend)
134 __mcip_cmd(CMD_ICI_GENERATE_IRQ, cpu);
135 }
136
137
arc_ici_handler(void)138 void arc_ici_handler(void)
139 {
140 unsigned int senders, c;
141
142
143 __mcip_cmd(CMD_ICI_CHECK_SOURCE, 0);
144
145 senders = _lr(AUX_MCIP_READBK); /* 1,2,4,8... */
146
147 /* No support interrupt coalescing yet */
148 c = __ffs(senders); /* 0,1,2,3 */
149 __mcip_cmd(CMD_ICI_GENERATE_ACK, c);
150 }
151