1/*
2 * init_gic.S
3 *
4 *  Created on: Jan 12, 2011
5 *  Author: MIPS TECHNOLOGIES, INC
6 *  Initialization of the Global Interrupt Conrtoller
7*/
8/*
9 Unpublished work (c) MIPS Technologies, Inc.  All rights reserved.  Unpublished rights reserved
10under the copyright laws of the United States of America and other countries.
11
12This code is confidential and proprietary to MIPS Technologies, Inc. ("MIPS Technologies") and
13may be disclosed only as permitted in writing by MIPS Technologies or an authorized third party.
14Any copying, reproducing, modifying, use or disclosure of this code (in whole or in part) that is
15not expressly permitted in writing by MIPS Technologies or an authorized third party is strictly
16prohibited. At a minimum, this code is protected under trade secret, unfair competition, and
17copyright laws. Violations thereof may result in criminal penalties and fines.
18
19MIPS Technologies reserves the right to change this code to improve function, design or
20otherwise. MIPS Technologies does not assume any liability arising out of the application or use
21of this code, or of any error or omission in such code.  Any warranties, whether express, statutory,
22implied or otherwise, including but not limited to the implied warranties of merchantability or
23fitness for a particular purpose, are excluded.  Except as expressly provided in any written license
24agreement from MIPS Technologies or an authorized third party, the furnishing of this code does
25not give recipient any license to any intellectual property rights, including any patent rights, that
26cover this code.
27
28This code shall not be exported, reexported, transferred, or released, directly or indirectly, in
29violation of the law of any country or international law, regulation, treaty, Executive Order,
30statute, amendments or supplements thereto.  Should a conflict arise regarding the export,
31reexport, transfer, or release of this code, the laws of the United States of America shall be
32the governing law.
33
34This code may only be disclosed to the United States government ("Government"), or to
35Government users, with prior written consent from MIPS Technologies or an authorized third
36party.  This code constitutes one or more of the following: commercial computer software,
37commercial computer software documentation or other commercial items.  If the user of this
38code, or any related documentation of any kind, including related technical data or manuals, is an
39agency, department, or other entity of the Government, the use, duplication, reproduction, release,
40modification, disclosure, or transfer of this code, or any related documentation of any kind, is
41restricted in accordance with Federal Acquisition Regulation 12.212 for civilian agencies and
42Defense Federal Acquisition Regulation Supplement 227.7202 for military agencies.  The use of
43this code by the Government is further restricted in accordance with the terms of the license
44agreement(s) and/or applicable contract terms and conditions covering this code from MIPS
45Technologies or an authorized third party.
46*/
47
48#include <boot.h>
49#include <regdef.h>
50#include <cps.h>
51
52	.set	noreorder           // Don't allow the assembler to reorder instructions.
53	.set	noat                // Don't allow the assembler to use r1(at) for synthetic instr.
54
55/**************************************************************************************
56**************************************************************************************/
57LEAF(init_gic)
58
59    beqz    r11_is_cps, done_gic					// Skip if non-CPS.
60    nop
61
62    la      a1, GCR_GIC_STATUS + GCR_CONFIG_ADDR	// Read GCR_GIC_STATUS
63    lw      a0, 0(a1)
64    ext     a0, a0, GIC_EX, GIC_EX_S				// Isolate  GCR_GIC_STATUS[GIC_EX].
65    beqz    a0, done_gic							// If no gic then skip.
66    nop
67
68    bnez    r23_cpu_num, init_vpe_gic				// Only core0 vpe0 inits shared portion.
69    nop
70
71    li      a1, GCR_CONFIG_ADDR + GCR_GIC_BASE  	// Locate and enable GIC
72    li      a0, GIC_P_BASE_ADDR | 1 				// Physical address + enable bit
73    sw      a0, 0(a1)
74
75    // Verify gic is 5 "slices" of 8 interrupts giving 40 interrupts.
76    li      a1, GIC_BASE_ADDR						// load GIC KSEG0 Address
77    lw      a0, GIC_SH_CONFIG(a1)					// GIC_SH_CONFIG
78    ext     a0, a0, NUMINTERRUPTS, NUMINTERRUPTS_S		// NUMINTERRUPTS (actually slices - 1)
79    li      a3, 4
80    beq     a0, a3, configure_slices
81    nop
82    sdbbp   // Failed assertion that gic implements 40 external interrupts.
83
84configure_slices:
85    // Hardcoded to set up the last 16 of 40 external interrupts (24..39) for IPI.
86    // First interrupts 24... 31 (top 8 bits of 31_0 registers)
87    li      a0, 0xff000000
88    sw      a0, GIC_SH_RMASK31_0(a1)	// (disable      0..31)
89    sw      a0, GIC_SH_POL31_0(a1)		// (high/rise   24..31)
90    sw      a0, GIC_SH_TRIG31_0(a1)		// (edge        24..31)
91    sw      a0, GIC_SH_SMASK31_00(a1)	// (enable      24..31)
92
93    // Then interrupts 32...40  (lower 8 bits of 63_32 registers)
94    li      a0, 0xff
95    sw      a0, GIC_SH_RMASK63_32(a1)	// (disable     32..63)
96    sw      a0, GIC_SH_POL63_32(a1)		// (high/rise   32..39)
97    sw      a0, GIC_SH_TRIG63_32(a1)	// (edge        32..39)
98    sw      a0, GIC_SH_SMASK63_32(a1)	// (enable      32..39)
99
100    // Initialize configuration of shared interrupts
101
102    // Direct GIC_int24..39 to vpe 0..7
103    // MIPS Linux convention that last 16 interrupts implemented be set aside for IPI signaling.
104    // (The actual interrupts are tied low and software sends interrupts via GIC_SH_WEDGE writes.)
105    li      a0, 1                        // set bit 0 for CORE0 or for MT vpe0
106    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 24) (a1) // Source 24 to VPE 0
107    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 32) (a1) // Source 32 to VPE 0
108    sll     a0, a0, 1          // set bit 1 for CORE1 or for MT vpe1
109    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 25) (a1) // Source 25 to VPE 1
110    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 33) (a1) // Source 33 to VPE 1
111    sll     a0, a0, 1          // set bit 2 for CORE2 or for MT vpe2
112    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 26) (a1) // Source 26 to VPE 2
113    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 34) (a1) // Source 34 to VPE 2
114    sll     a0, a0, 1          // set bit 3 for CORE3 or for MT vpe3
115 	sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 27) (a1) // Source 27 to VPE 3
116    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 35) (a1) // Source 35 to VPE 3
117    sll     a0, a0, 1          // set bit 4 for CORE4 or for MT vpe4
118 	sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 28) (a1) // Source 28 to VPE 4
119    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 36) (a1) // Source 36 to VPE 4
120    sll     a0, a0, 1          // set bit 5 for CORE5 or for MT vpe5
121 	sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 29) (a1) // Source 29 to VPE 5
122    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 37) (a1) // Source 37 to VPE 5
123    sll     a0, a0, 1          // set bit 6 for CORE6 or for MT vpe6
124 	sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 30) (a1) // Source 30 to VPE 6
125    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 38) (a1) // Source 38 to VPE 6
126    sll     a0, a0, 1          // set bit 7 for CORE7 or for MT vpe7
127 	sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 31) (a1) // Source 31 to VPE 7
128    sw      a0, GIC_SH_MAP0_VPE31_0 + (GIC_SH_MAP_SPACER * 39) (a1) // Source 39 to VPE 7
129
130init_vpe_gic:
131
132    // Initialize configuration of per Core or for MT vpe interrupts
133    li      a1, (GIC_BASE_ADDR | GIC_CORE_LOCAL_SECTION_OFFSET)
134    lw      a3, GIC_COREL_CTL(a1)
135
136map_timer_int:
137    ext     a0, a3, TIMER_ROUTABLE, TIMER_ROUTABLE_S
138    beqz    a0, map_perfcount_int
139    nop
140
141    li      a0, 0x80000005               // Int5 is selected for timer routing
142    sw      a0, GIC_COREL_TIMER_MAP(a1)
143
144map_perfcount_int:
145    ext     a0, a3, PERFCOUNT_ROUTABLE, PERFCOUNT_ROUTABLE_S
146    beqz    a0, done_gic
147    nop
148    li      a0, 0x80000004               // Int4 is selected for performance routing
149    sw      a0, GIC_COREL_PERFCTR_MAP(a1)
150
151done_gic:
152    jr      ra
153    nop
154
155END(init_gic)
156