1 /*
2 * Copyright (c) 2014, Mentor Graphics Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. Neither the name of Mentor Graphics Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
30 /**************************************************************************
31 * FILE NAME
32 *
33 * platform.c
34 *
35 * DESCRIPTION
36 *
37 * This file is the Implementation of IPC hardware layer interface
38 * for Xilinx Zynq ZC702EVK platform.
39 *
40 **************************************************************************/
42 #include "openamp/hil.h"
43 #include "openamp/machine/machine_common.h"
45 /* ------------------------- Macros --------------------------*/
46 #define ESAL_DP_SLCR_BASE 0xF8000000
47 #define PERIPH_BASE 0xF8F00000
48 #define GIC_DIST_BASE (PERIPH_BASE + 0x00001000)
49 #define GIC_DIST_SOFTINT 0xF00
50 #define GIC_SFI_TRIG_CPU_MASK 0x00FF0000
51 #define GIC_SFI_TRIG_SATT_MASK 0x00008000
52 #define GIC_SFI_TRIG_INTID_MASK 0x0000000F
53 #define GIC_CPU_ID_BASE (1 << 4)
54 #define A9_CPU_SLCR_RESET_CTRL 0x244
55 #define A9_CPU_SLCR_CLK_STOP (1 << 4)
56 #define A9_CPU_SLCR_RST (1 << 0)
58 #define unlock_slcr() HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x08, 0xDF0DDF0D)
59 #define lock_slcr() HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x04, 0x767B767B)
62 /* L2Cpl310 L2 cache controller base address. */
63 #define HIL_PL130_BASE 0xF8F02000
65 /********************/
66 /* Register offsets */
67 /********************/
69 #define HIL_PL130_INVALLINE 0x770
70 #define HIL_PL130_CLEANINVLINE 0x7F0
73 #define HIL_PA_SBZ_MASK ~(HIL_CACHE_LINE_SIZE - 1UL)
74 #define HIL_CACHE_LINE_SIZE 32
75 #define HIL_CACHE_INV_ALL_WAYS 0xFF
76 #define HIL_CACHE_UNLOCK_ALL_WAYS 0xFFFF0000
77 #define HIL_CACHE_CLEAR_INT 0x1FF
79 /*--------------------------- Declare Functions ------------------------ */
80 static int _enable_interrupt(struct proc_vring *vring_hw);
81 static void _notify(int cpu_id, struct proc_intr *intr_info);
82 static int _boot_cpu(int cpu_id, unsigned int load_addr);
83 static void _shutdown_cpu(int cpu_id);
85 /*--------------------------- Globals ---------------------------------- */
86 struct hil_platform_ops proc_ops = {
87 .enable_interrupt = _enable_interrupt,
88 .notify = _notify,
89 .boot_cpu = _boot_cpu,
90 .shutdown_cpu = _shutdown_cpu,
91 };
93 static int _enable_interrupt(struct proc_vring *vring_hw)
94 {
96 /* Register ISR */
97 env_register_isr(vring_hw->intr_info.vect_id, vring_hw, platform_isr);
99 /* Enable the interrupts */
100 env_enable_interrupt(vring_hw->intr_info.vect_id,
101 vring_hw->intr_info.priority,
102 vring_hw->intr_info.trigger_type);
103 return 0;
104 }
106 static void _notify(int cpu_id, struct proc_intr *intr_info)
107 {
109 unsigned long mask = 0;
111 mask = ((1 << (GIC_CPU_ID_BASE + cpu_id)) | (intr_info->vect_id))
112 & (GIC_SFI_TRIG_CPU_MASK | GIC_SFI_TRIG_INTID_MASK);
114 HIL_MEM_WRITE32((GIC_DIST_BASE + GIC_DIST_SOFTINT), mask);
115 }
117 extern char zynq_trampoline;
118 extern char zynq_trampoline_jump;
119 extern char zynq_trampoline_end;
121 static int _boot_cpu(int cpu_id, unsigned int load_addr)
122 {
123 unsigned int reg;
124 unsigned int tramp_size;
125 unsigned int tramp_addr = 0;
127 if (load_addr) {
128 tramp_size = zynq_trampoline_end - zynq_trampoline;
129 if ((load_addr < tramp_size) || (load_addr & 0x3)) {
130 return -1;
131 }
133 tramp_size = &zynq_trampoline_jump - &zynq_trampoline;
135 /*
136 * Trampoline code is copied to address 0 from where remote core is expected to
137 * fetch first instruction after reset.If master is using the address 0 then
138 * this mem copy will screwed the system. It is user responsibility to not
139 * copy trampoline code in such cases.
140 *
141 */
142 env_memcpy((char *)tramp_addr, &zynq_trampoline, tramp_size);
143 /* Write image address at the word reserved at the trampoline end */
144 HIL_MEM_WRITE32((char *)(tramp_addr + tramp_size), load_addr);
145 }
147 unlock_slcr();
149 reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL);
150 reg &= ~(A9_CPU_SLCR_CLK_STOP << cpu_id);
151 HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);
152 /* De-assert reset signal and start clock to start the core */
153 reg &= ~(A9_CPU_SLCR_RST << cpu_id);
154 HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);
156 lock_slcr();
158 return 0;
159 }
161 static void _shutdown_cpu(int cpu_id)
162 {
163 unsigned int reg;
165 unlock_slcr();
167 reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL);
168 /* Assert reset signal and stop clock to halt the core */
169 reg |= (A9_CPU_SLCR_CLK_STOP | A9_CPU_SLCR_RST) << cpu_id;
170 HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);
172 lock_slcr();
173 }