zynqmp: drivers use platform_isr instead of hil_isr
[processor-sdk/open-amp.git] / lib / system / generic / machine / zynq7 / machine_system.c
1 /*
2  * Copyright (c) 2014, Mentor Graphics Corporation
3  * All rights reserved.
4  *
5  * Copyright (c) 2015 Xilinx, Inc. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include <stdio.h>
32 #include <string.h>
33 #include "baremetal.h"
34 #include "machine_system.h"
35 #include "openamp/env.h"
36 #include "openamp/hil.h"
38 static inline unsigned int get_cpu_id_arm(void)
39 {
40         unsigned long cpu_id = 0;
42         asm volatile ("MRC p15 ,"
43                       "0," "%0," "c0," "c0," "5":[cpu_id] "=&r"(cpu_id)
44                       : /* No inputs */ );
46         /*
47          * Return cpu id to caller, extract last two bits from Multiprocessor
48          * Affinity Register */
49         return (cpu_id & 0x03);
50 }
52 int platform_interrupt_enable(unsigned int vector_id, unsigned int polarity,
53                               unsigned int priority)
54 {
55         unsigned long reg_offset;
56         unsigned long bit_shift;
57         unsigned long temp32 = 0;
58         unsigned long targ_cpu;
60         temp32 = get_cpu_id_arm();
62         /* Determine the necessary bit shift in this target / priority register
63            for this interrupt vector ID */
64         bit_shift = ((vector_id) % 4) * 8;
66         /* Build a target value based on the bit shift calculated above and the CPU core
67            that this code is executing on */
68         targ_cpu = (1 << temp32) << bit_shift;
70         /* Determine the Global interrupt controller target / priority register
71            offset for this interrupt vector ID
72            NOTE:  Each target / priority register supports 4 interrupts */
73         reg_offset = ((vector_id) / 4) * 4;
75         /* Read-modify-write the priority register for this interrupt */
76         temp32 = MEM_READ32(INT_GIC_DIST_BASE + INT_GIC_DIST_PRI + reg_offset);
78         /* Set new priority. */
79         temp32 |= (priority << (bit_shift + 4));
80         MEM_WRITE32(INT_GIC_DIST_BASE + INT_GIC_DIST_PRI + reg_offset, temp32);
82         /* Read-modify-write the target register for this interrupt to allow this
83            cpu to accept this interrupt */
84         temp32 =
85             MEM_READ32(INT_GIC_DIST_BASE + INT_GIC_DIST_TARGET + reg_offset);
86         temp32 |= targ_cpu;
87         MEM_WRITE32(INT_GIC_DIST_BASE + INT_GIC_DIST_TARGET + reg_offset,
88                     temp32);
90         /* Determine the Global interrupt controller enable set register offset
91            for this vector ID
92            NOTE:  There are 32 interrupts in each enable set register */
93         reg_offset = (vector_id / 32) * 4;
95         /* Write to the appropriate bit in the enable set register for this
96            vector ID to enable the interrupt */
98         temp32 = (1UL << (vector_id - (reg_offset * 0x08)));
99         MEM_WRITE32(INT_GIC_DIST_BASE + INT_GIC_DIST_ENABLE_SET + reg_offset,
100                     temp32);
102         /* Return the vector ID */
103         return (vector_id);
106 int platform_interrupt_disable(unsigned int vector_id)
108         unsigned long reg_offset;
109         unsigned long bit_shift;
110         unsigned long temp32 = 0;
111         unsigned long targ_cpu;
113         temp32 = get_cpu_id_arm();
115         /* Determine the Global interrupt controller enable set register offset
116            for this vector ID
117            NOTE:  There are 32 interrupts in each enable set register */
118         reg_offset = (vector_id / 32) * 4;
120         /* Write to the appropriate bit in the enable clear register for this
121            vector ID to disable the interrupt */
123         MEM_WRITE32(INT_GIC_DIST_BASE + INT_GIC_DIST_ENABLE_CLEAR + reg_offset,
124                     (1UL << (vector_id - (reg_offset * 0x08))));
126         /* Determine the Global interrupt controller target register offset for
127            this interrupt vector ID
128            NOTE:  Each target register supports 4 interrupts */
129         reg_offset = (vector_id / 4) * 4;
131         /* Determine the necessary bit shift in this target register for this
132            vector ID */
133         bit_shift = (vector_id % 4) * 8;
135         /* Build a value based on the bit shift calculated above and the CPU core
136            that this code is executing on */
137         targ_cpu = (1 << temp32) << bit_shift;
139         /* Read-modify-write the target register for this interrupt and remove this cpu from
140            accepting this interrupt */
141         temp32 =
142             MEM_READ32(INT_GIC_DIST_BASE + INT_GIC_DIST_TARGET + reg_offset);
143         temp32 &= ~targ_cpu;
145         MEM_WRITE32(INT_GIC_DIST_BASE + INT_GIC_DIST_TARGET + reg_offset,
146                     temp32);
148         /* Return the vector ID */
149         return (vector_id);
152 int old_value = 0;
154 void restore_global_interrupts()
156         ARM_AR_INT_BITS_SET(old_value);
159 void disable_global_interrupts()
161         int value = 0;
162         ARM_AR_INT_BITS_GET(&value);
163         if (value != old_value) {
164                 ARM_AR_INT_BITS_SET(ARM_AR_INTERRUPTS_DISABLE_BITS);
165                 old_value = value;
166         }
169 void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr,
170                              unsigned int size, unsigned int flags)
172         int is_mem_mapped = 0;
173         int cache_type = 0;
175         if ((flags & (0x0f << 4)) == MEM_MAPPED) {
176                 is_mem_mapped = 1;
177         }
179         if ((flags & 0x0f) == WB_CACHE) {
180                 cache_type = WRITEBACK;
181         } else if ((flags & 0x0f) == WT_CACHE) {
182                 cache_type = WRITETHROUGH;
183         } else {
184                 cache_type = NOCACHE;
185         }
187         arm_ar_map_mem_region(vrt_addr, phy_addr, size, is_mem_mapped,
188                               cache_type);
191 void platform_cache_all_flush_invalidate()
193         ARM_AR_MEM_DCACHE_ALL_OP(1);
196 void platform_cache_disable()
198         ARM_AR_MEM_CACHE_DISABLE();
201 unsigned long platform_vatopa(void *addr)
203         return (((unsigned long)addr & (~(0x0fff << 20))) | (0x08 << 24));
206 void *platform_patova(unsigned long addr)
208         return ((void *)addr);
212 void platform_isr(int vect_id, void * data)
214     (void)vect_id;
215     hil_isr(((struct proc_vring *)data));