3 * ________ _________ ____ / __ \/ ___/
4 * / ___/ _ \/ ___/ __ \/ __ \/ / / /\__ \
5 * / / / __/ /__/ /_/ / / / / /_/ /___/ /
6 * /_/ \___/\___/\____/_/ /_/\____//____/
8 * ======================================================================
10 * title: Architecture specific code - Microblaze, Xilkernel
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
29 #include <semaphore.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
{
57 volatile uint32_t *ptr
;
59 unsigned int fifo_fill
;
63 struct osif_intc_dev
{
64 volatile uint32_t *ptr
;
69 unsigned int irq_enable_count
;
74 struct osif_fifo_dev
*osif_fifo_dev
;
75 struct osif_intc_dev osif_intc_dev
;
77 int reconos_osif_open(int num
) {
81 static unsigned int osif_fifo_hw2sw_fill(struct osif_fifo_dev
*dev
) {
84 reg
= dev
->ptr
[OSIF_FIFO_RECV_STATUS_REG
];
85 if (reg
& OSIF_FIFO_RECV_STATUS_EMPTY_MASK
)
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
;
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
);
142 return dev
->ptr
[OSIF_FIFO_RECV_REG
];
145 void reconos_osif_write(int fd
, uint32_t data
) {
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
;
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
186 int reconos_proc_control_get_num_hwts(int fd
) {
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
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
) {
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
) {
222 proc_control_dev
.hwt_reset
[num
/ 32] |= 0x1 << num
% 32;
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
) {
232 int baseaddr
, bytesize
,linelen
;
234 // these parameters need to be adjusted to the architecture
236 baseaddr
= 0x20000000;
237 // C_DCACHE_BYTE_SIZE
238 bytesize
= 64 * 1024;
239 // C_DCACHE_LINE_LEN * 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
;
257 inline void init_icap() {
258 XHwIcap_Config
*icap_cfg
;
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");
275 int load_partial_bitstream(uint32_t *bitstream
, unsigned int bitstream_length
) {
278 pthread_mutex_lock(&icap_mutex
);
282 res
= XHwIcap_DeviceWrite(&icap
, bitstream
, bitstream_length
);
284 pthread_mutex_unlock(&icap_mutex
);
286 if (res
== XST_SUCCESS
)
293 /* == Initialization function =========================================== */
295 void reconos_drv_init() {
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
));
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);