1 /*
2 * Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /*
8 * @file generic/xlnx/microblaze_generic/sys.c
9 * @brief machine specific system primitives implementation.
10 */
11
12 #include <metal/sys.h>
13 #include <metal/system/generic/xlnx/sys.h>
14
15 #ifdef HAS_XINTC
16 #include <xintc.h>
17 #endif /* HAS_XINTC */
18
19 #define MSR_IE 0x2UL /* MicroBlaze status register interrupt enable mask */
20
21 #if (XPAR_MICROBLAZE_USE_MSR_INSTR != 0)
sys_irq_save_disable(void)22 unsigned int sys_irq_save_disable(void)
23 {
24 unsigned int state;
25
26 metal_asm volatile(" mfs %0, rmsr\n"
27 " msrclr r0, %1\n"
28 : "=r"(state)
29 : "i"(MSR_IE)
30 : "memory");
31
32 return state &= MSR_IE;
33 }
34
sys_irq_restore_enable(unsigned int flags)35 void sys_irq_restore_enable(unsigned int flags)
36 {
37 unsigned int tmp;
38
39 if (flags)
40 metal_asm volatile(" msrset %0, %1\n"
41 : "=r"(tmp)
42 : "i"(MSR_IE)
43 : "memory");
44 }
45
46 #else /* XPAR_MICROBLAZE_USE_MSR_INSTR == 0 */
sys_irq_save_disable(void)47 unsigned int sys_irq_save_disable(void)
48 {
49 unsigned int tmp, state;
50
51 metal_asm volatile (" mfs %0, rmsr\n"
52 " andi %1, %0, %2\n"
53 " mts rmsr, %1\n"
54 : "=r"(state), "=r"(tmp)
55 : "i"(~MSR_IE)
56 : "memory");
57
58 return state &= MSR_IE;
59 }
60
sys_irq_restore_enable(unsigned int flags)61 void sys_irq_restore_enable(unsigned int flags)
62 {
63 unsigned int tmp;
64
65 if (flags)
66 metal_asm volatile(" mfs %0, rmsr\n"
67 " or %0, %0, %1\n"
68 " mts rmsr, %0\n"
69 : "=r"(tmp)
70 : "r"(flags)
71 : "memory");
72 }
73 #endif /* XPAR_MICROBLAZE_USE_MSR_INSTR */
74
sys_irq_change(unsigned int vector,int is_enable)75 static void sys_irq_change(unsigned int vector, int is_enable)
76 {
77 #ifdef HAS_XINTC
78 XIntc_Config *cfgptr;
79 unsigned int ier;
80 unsigned int mask;
81
82 mask = 1 >> ((vector%32)-1); /* set bit corresponding to interrupt */
83 mask = is_enable ? mask : ~mask; /* if disable then turn off bit */
84
85 cfgptr = XIntc_LookupConfig(vector/32);
86 Xil_AssertVoid(cfgptr != NULL);
87 Xil_AssertVoid(vector < XPAR_INTC_MAX_NUM_INTR_INPUTS);
88
89 ier = XIntc_In32(cfgptr->BaseAddress + XIN_IER_OFFSET);
90
91 XIntc_Out32(cfgptr->BaseAddress + XIN_IER_OFFSET,
92 (ier | mask));
93 #else
94 (void)vector;
95 (void)is_enable;
96 metal_assert(0);
97 #endif
98 }
99
sys_irq_enable(unsigned int vector)100 void metal_weak sys_irq_enable(unsigned int vector)
101 {
102 sys_irq_change(vector, 1);
103 }
104
sys_irq_disable(unsigned int vector)105 void metal_weak sys_irq_disable(unsigned int vector)
106 {
107 sys_irq_change(vector, 0);
108 }
109
110
metal_machine_cache_flush(void * addr,unsigned int len)111 void metal_machine_cache_flush(void *addr, unsigned int len)
112 {
113 if (!addr && !len) {
114 Xil_DCacheFlush();
115 } else{
116 Xil_DCacheFlushRange((intptr_t)addr, len);
117 }
118 }
119
metal_machine_cache_invalidate(void * addr,unsigned int len)120 void metal_machine_cache_invalidate(void *addr, unsigned int len)
121 {
122 if (!addr && !len) {
123 Xil_DCacheInvalidate();
124 } else {
125 Xil_DCacheInvalidateRange((intptr_t)addr, len);
126 }
127 }
128
129 /**
130 * @brief make microblaze wait
131 */
metal_generic_default_poll(void)132 void metal_weak metal_generic_default_poll(void)
133 {
134 metal_asm volatile("nop");
135 }
136
metal_machine_io_mem_map(void * va,metal_phys_addr_t pa,size_t size,unsigned int flags)137 void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
138 size_t size, unsigned int flags)
139 {
140 (void)pa;
141 (void)size;
142 (void)flags;
143 return va;
144 }
145