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