📄 bf533_io.c
字号:
#include "bfin-sim.h"#include "mach.h"#include "types.h"#include "bf533_io.h"#include "dma.h"#include "bf533_irq.h"#include "sysname.h"#include "skyeye_config.h"#include <stdio.h>#include <fcntl.h>#include <signal.h>extern void dma_mem_cpy (unsigned long src, unsigned long dst, int size);#define DEBUG 0#if DEBUG#define DBG_PRINT(a...) printf(##a)#else#define DBG_PRINT(a...)#endif#define IO_ERR {printf("\n%s io error!!!addr=0x%x,pc=0x%x\n",__FUNCTION__,addr,PCREG);raise (SIGILL);}#define MALLOC_ERR {printf("\n%s malloc error!\n",__FUNCTION__);skyeye_exit(-1);}/*declare the device io functions*/declare_device (uart) declare_device (wd) declare_device (core_int) declare_device (dma) declare_device (dpmc) declare_device (deu) declare_device (ebiu) declare_device (sic) declare_device (l1mem) declare_device (l1dmem) declare_device (rtc) declare_device (core_timer) declare_device (pf) static void handle_irq (); static void bf533_disable_int (); static void bf533_enable_int (); typedef struct uart { bu16 rbr; bu16 thr; bu16 ier; bu16 iir; bu16 fcr; bu16 lcr; bu16 lsr; bu16 msr; bu16 scr; bu16 dll; bu16 dlh; bu16 gctl; } bf533_uart_t; static int uart_outfd; typedef struct dma_channel { bu32 next_desc_ptr; bu32 start_addr; bu32 x_count; bu32 x_modify; bu32 y_count; bu32 y_modify; bu32 curr_desc_ptr; bu32 curr_addr; bu32 irq_status; bu32 peripheral_map; bu32 curr_x_count; bu32 curr_y_count; } bf533_dma_channel_t; typedef struct l1mem { bu32 reg[L1MEM_IO_SIZE / 4]; } bf533_l1mem_t; typedef struct l1dmem { bu32 reg[L1DMEM_IO_SIZE / 4]; } bf533_l1dmem_t; typedef struct dma { bu16 tc_per; bu16 tc_cnt; bu32 bf533_dma_channel[12][16]; } bf533_dma_t; typedef struct ebiu { bu16 amgctl; bu16 ambctl0; bu16 ambctl1; bu16 sdgctl; bu16 sdbctl; bu16 sdrrc; bu16 sdstat; } bf533_ebiu_t; typedef struct core_int { bu32 evt[16]; bu32 imask; bu32 ipend; bu32 iprio; bu32 ilat; } bf533_core_int_t; typedef struct wd { bu16 ctl; bu32 cnt; bu32 stat; } bf533_wd_t; typedef struct deu { bu32 dspid; } bf533_deu_t; typedef struct dpmc { bu16 pll_ctl; bu16 pll_stat; bu16 pll_lockcnt; bu16 vr_ctl; bu16 pll_div; } bf533_dpmc_t; typedef struct sic { bu32 swrst; bu32 syscr; bu32 sic_imask; bu32 sic_iar[3]; bu32 sic_isr; bu32 sic_iwr; } bf533_sic_t; typedef struct rtc { bu32 stat; bu32 ictl; bu32 istat; bu32 swcnt; bu32 alarm; bu32 pren; } bf533_rtc_t; typedef struct core_timer { bu32 tcntl; bu32 tperiod; bu32 tscale; bu32 tcount; } bf533_core_timer_t; typedef struct pf { bu32 fio_flag_d; bu32 fio_flag_c; bu32 fio_flag_s; bu32 fio_dir; bu32 fio_polar; } bf533_pf_t; typedef struct bf533_io { bf533_uart_t uart; /* Receive data register */ bf533_dma_t dma; bf533_ebiu_t ebiu; bf533_core_int_t core_int; bf533_wd_t wd; bf533_deu_t deu; bf533_dpmc_t dpmc; bf533_sic_t sic; bf533_l1mem_t l1mem; bf533_l1dmem_t l1dmem; bf533_rtc_t rtc; bf533_core_timer_t core_timer; bf533_pf_t pf; } bf533_io_t; bf533_io_t io;/*also be called by raise inst and except*/ static void bf533_set_int (int irq){// if(irq != CORE_TIMER_IRQ & irq != 0) // fprintf(PF,"####################irq=%d,in %s\n",irq,__FUNCTION__); if ((io.core_int.imask | 0x1f) & (1 << irq)) { //if(irq != CORE_TIMER_IRQ & irq != 0) // fprintf(PF,"####################irq=%d,in %s\n",irq,__FUNCTION__); /*set the corresponding int bit to 1 in ilat */ io.core_int.ilat |= (1 << irq); }}static voidbf533_clear_int (int irq_no_use){ int irq; /*fix me, trigger the corresponding int according to some prio check, */ for (irq = 1; irq < 16; irq++) { /*check there is a pending int for clear */ if ((io.core_int.ipend >> irq) & 0x1) { /*clear the int bit */ io.core_int.ipend &= ~(1 << irq); /*clear corresponding int in the device */ if (irq == CORE_TIMER_IRQ) { io.core_timer.tcntl &= ~0x8; } if (io.core_int.ipend == 0x0) { /*There is no interrupt to handle, switch mode */ MODE = USR_MODE; OLDSPREG = SPREG; SPREG = USPREG; } return; } }}static voidhandle_irq (){ int irq = 0; if (OLDPCREG < 0x1000) { printf ("in %s,pc=%x,jump to 0x%x,olderpc=0x%x\n", __FUNCTION__, PCREG, OLDPCREG, OLDERPCREG); raise (SIGINT); } if (irq != CORE_TIMER_IRQ && irq != 0) fprintf (PF, "1####################irq=%d,in %s\n", irq, __FUNCTION__); /*if global int is disabled,just return */ if (io.core_int.ipend & 0x10) { return; } /*fix me, trigger the corresponding int according to some prio check, */ for (irq = 0; irq < 16; irq++) { if ((io.core_int.ilat >> irq) & 0x1) { /*current there is a high priority pending int for handle,wait until it finish */ if (irq != CORE_TIMER_IRQ) fprintf (PF, "2####################irq=%d,in %s\n", irq, __FUNCTION__); if ((io.core_int.ipend >> irq) & 0x1) { return; } if (irq != CORE_TIMER_IRQ) fprintf (PF, "3####################irq=%d,in %s\n", irq, __FUNCTION__); /* set ipend bit , and clear ilat */ io.core_int.ilat &= ~(1 << irq); io.core_int.ipend |= (1 << irq); /*now if did_jump in interp.c is set, the following code is executed twice,maybe it not make something wrong */ if (LC1REG && OLDPCREG == LB1REG && --LC1REG) { //printf("int in the end of loop,PC=%x\n",PCREG); PCREG = LT1REG; } else if (LC0REG && OLDPCREG == LB0REG && --LC0REG) { //printf("int in the end of loop,PC=%x\n",PCREG); PCREG = LT0REG; } /*clear corresponding int in the device */ if (irq == CORE_TIMER_IRQ) { //return; io.core_timer.tcntl &= ~0x8;// fprintf(PF,"##Timer IRQ:PC=0x%x,\n",PCREG); } else { fprintf (PF, "## Other IRQ:irq=%d,\n", irq); } /*switch mode */ if (MODE == USR_MODE) { MODE = SUPER_MODE; USPREG = SPREG; SPREG = OLDSPREG; } /*save pc to reti,jump to the corresponding vector */ if (irq == EXCEPT_IRQ) { fprintf (PF, "##System Call:PC=0x%x, %s(),sys_number=%d,ipend=0x%x\n", PCREG, sys_name[PREG (0)], PREG (0), io.core_int.ipend); saved_state.retx = PCREG; } else { saved_state.reti = PCREG; } PCREG = io.core_int.evt[irq]; /*at the same time , disable global int for protecting reti */ bf533_disable_int (); return; } }}static voidbf533_disable_int (){ //printf("in %s\n",__FUNCTION__); io.core_int.ipend |= 0x10;}static voidbf533_enable_int (){ //printf("in %s\n",__FUNCTION__); io.core_int.ipend &= ~0x10;}static voidbf533_cli (bu32 * dreg){ *dreg = io.core_int.imask; //printf("cli,%x\n",*dreg); io.core_int.imask = 0x1f;}static voidbf533_sti (bu32 * dreg){ //printf("sti,%x\n",*dreg); io.core_int.imask = *dreg;}#define BF533_HZ 50static UART_OPEN = 0;//koodailar add for mingw 2005.12.18 ----------------------------------------#ifdef __MINGW32__static voidbf533_io_do_cycle (){}#elsestatic voidbf533_io_do_cycle (){ static int sclk_count = 0; static int timer_count = BF533_HZ; static int uart_tx_count = 0; sclk_count++; /*if global int is disabled */ /* if(sclk_count == io.core_timer.tscale+1){ sclk_count = 0; io.core_timer.tcount--; if(io.core_timer.tcount == 0){ bf533_set_int(CORE_TIMER_IRQ); io.core_timer.tcount = io.core_timer.tperiod; } } */ if (sclk_count == io.core_timer.tscale + 1) { sclk_count = 0; timer_count--; if (timer_count == 0) { timer_count = BF533_HZ; /*if previous timer int handle is not finished , this int is lost */ /*If core_timer enabled? */ if ((io.core_timer.tcntl & 0x2)) { io.core_timer.tcntl |= 0x8; bf533_set_int (CORE_TIMER_IRQ); uart_tx_count++; } } } if ((io.sic.sic_imask & 0x8000) && io.uart.ier & 0x2) { // printf("\nUART TX IRQ\n"); bf533_set_int (((io.sic.sic_iar[1] & 0xf0000000) >> 28) + 7); io.uart.iir = 0x2; io.sic.sic_isr |= 0x8000; uart_tx_count = 0; } if (!(io.uart.lsr & 0x1)) { fd_set rfds; struct timeval tv; FD_ZERO (&rfds); FD_SET (skyeye_config.uart.fd_in, &rfds); tv.tv_sec = 0; tv.tv_usec = 0; //printf("\nUART RX IRQ before selext\n"); if (select (skyeye_config.uart.fd_in + 1, &rfds, NULL, NULL, &tv) == 1) { //printf ("\nUART RX IRQ\n"); unsigned char buf; int n, i; n = read (skyeye_config.uart.fd_in, &buf, sizeof (buf)); if (n) { io.uart.rbr = buf; /*set DR bit in LSR */ io.uart.lsr |= 0x1; //printf("\nUART RX IRQ getchar\n"); } } } if ((io.sic.sic_imask & 0x4000) && (io.uart.ier & 0x1) && (io.uart.lsr & 0x1)) { io.uart.iir = 0x4; io.sic.sic_isr |= 0x4000; bf533_set_int (((io.sic.sic_iar[1] & 0xf000000) >> 24) + 7); } //static int UART_TX_COUNT = 100; handle_irq ();}#endif// end ---------------------------------------------------------------------- static bu8bf533_io_read_byte (bu32 addr){ switch (addr) { default: if (addr >= DMA_IO_START_ADDR && addr < DMA_IO_END_ADDR) { return dma_read_byte (addr); } else if (addr >= UART_IO_START_ADDR && addr < UART_IO_END_ADDR) { return uart_read_byte (addr); } else { IO_ERR; } }}static bu16bf533_io_read_word (bu32 addr){ switch (addr) { default: if (addr >= DMA_IO_START_ADDR && addr < DMA_IO_END_ADDR) { return dma_read_word (addr); } else if (addr >= UART_IO_START_ADDR && addr < UART_IO_END_ADDR) { return uart_read_word (addr); } else if (addr >= DPMC_IO_START_ADDR && addr < DPMC_IO_END_ADDR) { return dpmc_read_word (addr); } else if (addr >= EBIU_IO_START_ADDR && addr < EBIU_IO_END_ADDR) { return ebiu_read_word (addr); } else if (addr >= RTC_IO_START_ADDR && addr < RTC_IO_END_ADDR) { return rtc_read_word (addr); } else if (addr >= PF_IO_START_ADDR && addr < PF_IO_END_ADDR) { return pf_read_word (addr); } else { IO_ERR; } }}static bu32bf533_io_read_long (bu32 addr){ switch (addr) { default: if (addr >= DMA_IO_START_ADDR && addr < DMA_IO_END_ADDR) { return dma_read_long (addr); } else if (addr >= UART_IO_START_ADDR && addr < UART_IO_END_ADDR) { return uart_read_long (addr); } else if (addr >= DEU_IO_START_ADDR && addr < DEU_IO_END_ADDR) { return deu_read_long (addr); } else if (addr >= EBIU_IO_START_ADDR && addr < EBIU_IO_END_ADDR) { return ebiu_read_long (addr); } else if (addr >= SIC_IO_START_ADDR && addr < SIC_IO_END_ADDR) { return sic_read_long (addr); } else if (addr >= L1MEM_IO_START_ADDR && addr < L1MEM_IO_END_ADDR) { return l1mem_read_long (addr); } else if (addr >= L1DMEM_IO_START_ADDR && addr < L1DMEM_IO_END_ADDR) { return l1dmem_read_long (addr); } else if (addr >= CORE_INT_IO_START_ADDR && addr < CORE_INT_IO_END_ADDR) { return core_int_read_long (addr); } else if (addr >= RTC_IO_START_ADDR && addr < RTC_IO_END_ADDR) { return rtc_read_long (addr); } else if (addr >= CORE_TIMER_IO_START_ADDR && addr < CORE_TIMER_IO_END_ADDR) { return core_timer_read_long (addr); } else { IO_ERR; } }}static voidbf533_io_write_byte (bu32 addr, bu8 v){ switch (addr) { default: if (addr >= DMA_IO_START_ADDR && addr < DMA_IO_END_ADDR) { dma_write_byte (addr, v); } else if (addr >= UART_IO_START_ADDR && addr < UART_IO_END_ADDR) { uart_write_byte (addr, v); } else { IO_ERR; } } return;}static voidbf533_io_write_word (bu32 addr, bu16 v){ switch (addr) { default: if (addr >= DMA_IO_START_ADDR && addr < DMA_IO_END_ADDR) { dma_write_word (addr, v); } else if (addr >= UART_IO_START_ADDR && addr < UART_IO_END_ADDR) { uart_write_word (addr, v); } else if (addr >= EBIU_IO_START_ADDR && addr < EBIU_IO_END_ADDR) { ebiu_write_word (addr, v); } else if (addr >= WD_IO_START_ADDR && addr < WD_IO_END_ADDR) { wd_write_word (addr, v); } else if (addr >= DPMC_IO_START_ADDR && addr < DPMC_IO_END_ADDR) { dpmc_write_word (addr, v); } else if (addr >= RTC_IO_START_ADDR && addr < RTC_IO_END_ADDR) { rtc_write_word (addr, v); } else if (addr >= PF_IO_START_ADDR && addr < PF_IO_END_ADDR) { pf_write_word (addr, v); } else { IO_ERR; } } return;}static voidbf533_io_write_long (bu32 addr, bu32 v){ switch (addr) { default: if (addr >= DMA_IO_START_ADDR && addr < DMA_IO_END_ADDR) { dma_write_long (addr, v); } else if (addr >= UART_IO_START_ADDR && addr < UART_IO_END_ADDR) { uart_write_long (addr, v); } else if (addr >= EBIU_IO_START_ADDR && addr < EBIU_IO_END_ADDR) { ebiu_write_long (addr, v); } else if (addr >= CORE_INT_IO_START_ADDR && addr < CORE_INT_IO_END_ADDR) { core_int_write_long (addr, v); } else if (addr >= SIC_IO_START_ADDR && addr < SIC_IO_END_ADDR) { sic_write_long (addr, v); } else if (addr >= L1MEM_IO_START_ADDR && addr < L1MEM_IO_END_ADDR) { l1mem_write_long (addr, v); } else if (addr >= L1DMEM_IO_START_ADDR && addr < L1DMEM_IO_END_ADDR) { l1dmem_write_long (addr, v); } else if (addr >= RTC_IO_START_ADDR && addr < RTC_IO_END_ADDR) { rtc_write_long (addr, v); } else if (addr >= CORE_TIMER_IO_START_ADDR && addr < CORE_TIMER_IO_END_ADDR) { core_timer_write_long (addr, v); } else { IO_ERR; } } return;}bu16uart_read_word (bu32 addr){ bu16 data; //printf("bf533_uart_read,addr=%x\n",addr); bu32 offset = addr - UART_IO_START_ADDR; /* if(offset != 0 && offset != 0x14 && offset != 0xc && offset!=0x4) printf("###############offset=0x%x\n",offset); */ static int read_num = 0; switch (offset) { case 0x0: // RbR if (io.uart.lcr & 0x80) { data = io.uart.dlh; } if (read_num == 0) { read_num = 1; return 'k'; } if (read_num == 1) { io.uart.lsr &= ~0x1; io.sic.sic_isr &= ~0x4000; data = io.uart.rbr & 0xff; //io.uart.iir = 0x1; read_num = 0; fprintf (PF, "*****read rbr=%x,pc=%x,isr=%x\n", data, PCREG, io.sic.sic_isr); } break; case 0x4: // ier if (io.uart.lcr & 0x80) data = io.uart.dlh; else data = io.uart.ier; break; case 0x8: // iir data = io.uart.iir; //printf("read iir=%x,pc=%x\n",data,PCREG); io.uart.iir = 0x1; break; case 0xc: // lcr data = io.uart.lcr; break; case 0x10: // MCR data = 0x0; break; case 0x14: // LSR data = io.uart.lsr; //printf("read lsr=%x,pc=%x\n",data,PCREG); break; case 0x1c: // SCR data = io.uart.lcr; break; case 0x24: // SCR data = io.uart.gctl; break; default: IO_ERR; DBG_PRINT ("uart_read(%s=0x%08x)\n", "uart_reg", addr); break; } return (data);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -