added set -e to scripts
[reconos.git] / lib / arch / arch_microblaze_xilkernel.c
blob640ccdda152946505dbedc9fd1ae53a65b62c5db
1 /*
2 * ____ _____
3 * ________ _________ ____ / __ \/ ___/
4 * / ___/ _ \/ ___/ __ \/ __ \/ / / /\__ \
5 * / / / __/ /__/ /_/ / / / / /_/ /___/ /
6 * /_/ \___/\___/\____/_/ /_/\____//____/
8 * ======================================================================
10 * title: Architecture specific code - Microblaze, Xilkernel
12 * project: ReconOS
13 * author: Christoph RĂ¼thing, University of Paderborn
14 * description: Functions needed for ReconOS which are architecure
15 * specific and are implemented here.
17 * ======================================================================
21 #ifdef RECONOS_ARCH_microblaze
22 #ifdef RECONOS_OS_xilkernel
24 #include "arch.h"
26 #include "xhwicap.h"
28 #include <pthread.h>
29 #include <semaphore.h>
30 #include <sys/intr.h>
32 unsigned int NUM_HWTS = 0;
35 /* == OSIF related functions ============================================ */
37 #define OSIF_INTC_BASE_ADDR 0x7B400000
38 #define OSIF_INTC_MEM_SIZE 0x10000
39 #define OSIF_INTC_IRQ 3
41 #define OSIF_FIFO_BASE_ADDR 0x75A00000
42 #define OSIF_FIFO_MEM_SIZE 0x10
43 #define OSIF_FIFO_RECV_REG 0
44 #define OSIF_FIFO_SEND_REG 1
45 #define OSIF_FIFO_RECV_STATUS_REG 2
46 #define OSIF_FIFO_SEND_STATUS_REG 3
48 #define OSIF_FIFO_RECV_STATUS_EMPTY_MASK 0x1 << 31
49 #define OSIF_FIFO_SEND_STATUS_FULL_MASK 0x1 << 31
51 #define OSIF_FIFO_RECV_STATUS_FILL_MASK 0xFFFF
52 #define OSIF_FIFO_SEND_STATUS_REM_MASK 0xFFFF
54 struct osif_fifo_dev {
55 unsigned int index;
57 volatile uint32_t *ptr;
59 unsigned int fifo_fill;
60 sem_t wait;
63 struct osif_intc_dev {
64 volatile uint32_t *ptr;
66 uint32_t irq_reg;
67 uint32_t irq_enable;
69 unsigned int irq_enable_count;
71 pthread_mutex_t lock;
74 struct osif_fifo_dev *osif_fifo_dev;
75 struct osif_intc_dev osif_intc_dev;
77 int reconos_osif_open(int num) {
78 return num;
81 static unsigned int osif_fifo_hw2sw_fill(struct osif_fifo_dev *dev) {
82 uint32_t reg;
84 reg = dev->ptr[OSIF_FIFO_RECV_STATUS_REG];
85 if (reg & OSIF_FIFO_RECV_STATUS_EMPTY_MASK)
86 return 0;
87 else
88 return (reg & OSIF_FIFO_RECV_STATUS_EMPTY_MASK) + 1;
91 static inline void osif_intc_enable_interrupt(struct osif_intc_dev *dev, unsigned int irq) {
92 pthread_mutex_lock(&dev->lock);
94 dev->irq_enable |= 0x1 << irq % 32;
95 dev->ptr[0] = dev->irq_enable;
97 dev->irq_enable_count++;
99 pthread_mutex_unlock(&dev->lock);
102 static inline void osif_intc_disable_interrupt(struct osif_intc_dev *dev, unsigned int irq) {
103 pthread_mutex_lock(&dev->lock);
105 dev->irq_enable &= ~(0x1 << irq % 32);
106 dev->ptr[0] = dev->irq_enable;
108 dev->irq_enable_count--;
110 pthread_mutex_unlock(&dev->lock);
113 void osif_intc_interrupt(void *arg) {
114 struct osif_intc_dev *dev = &osif_intc_dev;
115 int i;
117 dev->irq_reg = dev->ptr[0] & dev->irq_enable;
119 for (i = 0; i < 32; i++) {
120 if ((dev->irq_reg >> i) & 0x1) {
121 osif_intc_disable_interrupt(dev, i);
123 osif_fifo_dev[i].fifo_fill = osif_fifo_hw2sw_fill(&osif_fifo_dev[i]);
124 sem_post(&osif_fifo_dev[i].wait);
129 uint32_t reconos_osif_read(int fd) {
130 struct osif_fifo_dev *dev = &osif_fifo_dev[fd];
132 if (dev->fifo_fill == 0) {
133 dev->fifo_fill = osif_fifo_hw2sw_fill(dev);
135 while (dev->fifo_fill == 0) {
136 osif_intc_enable_interrupt(&osif_intc_dev, fd);
137 sem_wait(&dev->wait);
141 dev->fifo_fill--;
142 return dev->ptr[OSIF_FIFO_RECV_REG];
145 void reconos_osif_write(int fd, uint32_t data) {
146 uint32_t reg;
148 do {
149 reg = osif_fifo_dev[fd].ptr[OSIF_FIFO_SEND_STATUS_REG];
150 } while (reg & OSIF_FIFO_SEND_STATUS_FULL_MASK);
152 osif_fifo_dev[fd].ptr[OSIF_FIFO_SEND_REG] = data;
155 void reconos_osif_close(int fd) {
156 // nothing to do here
160 /* == Proc control related functions ==================================== */
162 #define PROC_CONTROL_BASE_ADDR 0x6FE00000
163 #define PROC_CONTROL_MEM_SIZE 0x10000
165 #define PROC_CONTROL_NUM_HWTS_REG 0
166 #define PROC_CONTROL_PGD_ADDR_REG 1
167 #define PROC_CONTROL_PAGE_FAULT_ADDR_REG 2
168 #define PROC_CONTROL_TLB_HITS_REG 3
169 #define PROC_CONTROL_TLB_MISSES_REG 4
170 #define PROC_CONTROL_SYS_RESET_REG 5
171 #define PROC_CONTROL_HWT_RESET_REG 6
173 struct proc_control_dev {
174 volatile uint32_t *ptr;
175 uint32_t *hwt_reset;
176 size_t hwt_reset_count;
179 struct proc_control_dev proc_control_dev;
181 int reconos_proc_control_open() {
182 // nothing to do here
183 return 0;
186 int reconos_proc_control_get_num_hwts(int fd) {
187 return NUM_HWTS;
190 int reconos_proc_control_get_tlb_hits(int fd) {
191 return proc_control_dev.ptr[PROC_CONTROL_TLB_HITS_REG];
194 int reconos_proc_control_get_tlb_misses(int fd) {
195 return proc_control_dev.ptr[PROC_CONTROL_TLB_MISSES_REG];
198 uint32_t reconos_proc_control_get_fault_addr(int fd) {
199 // nothing to do here since no MMU present
200 while(1);
203 void reconos_proc_control_clear_page_fault(int fd) {
204 // nothing to do here since no MMU present
207 void reconos_proc_control_set_pgd(int fd) {
208 // nothing to do here since no MMU present
211 void reconos_proc_control_sys_reset(int fd) {
212 int i;
214 for (i = 0; i < NUM_HWTS; i++)
215 proc_control_dev.hwt_reset[i] = 0xFFFFFFFF;
216 proc_control_dev.ptr[PROC_CONTROL_SYS_RESET_REG] = 0;
219 void reconos_proc_control_hwt_reset(int fd, int num, int reset) {
220 if (num >= 0 && num < NUM_HWTS) {
221 if (reset)
222 proc_control_dev.hwt_reset[num / 32] |= 0x1 << num % 32;
223 else
224 proc_control_dev.hwt_reset[num / 32] &= ~(0x1 << num % 32);
226 proc_control_dev.ptr[PROC_CONTROL_HWT_RESET_REG + num / 32] = proc_control_dev.hwt_reset[num / 32];
230 void reconos_proc_control_cache_flush(int fd) {
231 int i;
232 int baseaddr, bytesize,linelen;
234 // these parameters need to be adjusted to the architecture
235 // C_DCACHE_BASEADDR
236 baseaddr = 0x20000000;
237 // C_DCACHE_BYTE_SIZE
238 bytesize = 64 * 1024;
239 // C_DCACHE_LINE_LEN * 4
240 linelen = 4 * 4;
242 for (i = 0; i < bytesize; i += linelen)
243 asm volatile ("wdc.flush %0, %1;" :: "d" (baseaddr), "d" (i));
246 void reconos_proc_control_close(int fd) {
247 // nothing to do here
251 /* == Reconfiguration related functions ================================= */
253 int is_configured = 0;
254 pthread_mutex_t icap_mutex;
255 XHwIcap icap;
257 inline void init_icap() {
258 XHwIcap_Config *icap_cfg;
259 int res;
261 if (!is_configured) {
262 pthread_mutex_init(&icap_mutex, NULL);
264 icap_cfg = XHwIcap_LookupConfig(0);
265 res = XHwIcap_CfgInitialize(&icap, icap_cfg,icap_cfg->BaseAddress);
266 if (res != XST_SUCCESS) {
267 panic("error initializing icap, aborting.\n");
268 exit(0);
271 is_configured = 1;
275 int load_partial_bitstream(uint32_t *bitstream, unsigned int bitstream_length) {
276 int res;
278 pthread_mutex_lock(&icap_mutex);
280 init_icap();
282 res = XHwIcap_DeviceWrite(&icap, bitstream, bitstream_length);
284 pthread_mutex_unlock(&icap_mutex);
286 if (res == XST_SUCCESS)
287 return 0;
288 else
289 return -1;
293 /* == Initialization function =========================================== */
295 void reconos_drv_init() {
296 int i;
298 proc_control_dev.ptr = (uint32_t *)PROC_CONTROL_BASE_ADDR;
299 NUM_HWTS = proc_control_dev.ptr[PROC_CONTROL_NUM_HWTS_REG];
302 // allocate memory for HWT resets
303 proc_control_dev.hwt_reset_count = NUM_HWTS / 32 + 1;
304 proc_control_dev.hwt_reset = (uint32_t*)malloc(proc_control_dev.hwt_reset_count * sizeof(uint32_t));
305 if (!proc_control_dev.hwt_reset)
306 panic("[reconos-proc-control] failed to allocate memory\n");
309 // reset entire system
310 for (i = 0; i < proc_control_dev.hwt_reset_count; i++)
311 proc_control_dev.hwt_reset[i] = 0xFFFFFFFF;
312 proc_control_dev.ptr[PROC_CONTROL_SYS_RESET_REG] = 0;
315 // allocate and initialize intc device
316 osif_intc_dev.ptr = (uint32_t *)OSIF_INTC_BASE_ADDR;
317 osif_intc_dev.irq_reg = 0;
318 osif_intc_dev.irq_enable = 0;
319 osif_intc_dev.ptr[0] = osif_intc_dev.irq_enable;
320 osif_intc_dev.irq_enable_count = 0;
321 pthread_mutex_init(&osif_intc_dev.lock, NULL);
323 register_int_handler(OSIF_INTC_IRQ, osif_intc_interrupt, NULL);
324 enable_interrupt(OSIF_INTC_IRQ);
327 // allocate and initialize osif devices
328 osif_fifo_dev = (struct osif_fifo_dev*)malloc(NUM_HWTS * sizeof(struct osif_fifo_dev));
329 if (!osif_fifo_dev)
330 panic("[reconos-osif] failed to allocate memory\n");
332 for (i = 0; i < NUM_HWTS; i++) {
333 osif_fifo_dev[i].index = i;
334 osif_fifo_dev[i].ptr = (uint32_t *)(OSIF_FIFO_BASE_ADDR + i * OSIF_FIFO_MEM_SIZE);
335 osif_fifo_dev[i].fifo_fill = 0;
336 sem_init(&osif_fifo_dev[i].wait, 0, 0);
340 #endif
341 #endif