📄 pati.c
字号:
if(led_on) /* set output to 1 */ reg |= 0x04000000; else reg &= ~0x04000000; sysconf->sc_sgpiodt2=reg; /* Data register */}void user_led1(int led_on){ volatile immap_t * immr = (immap_t *) CFG_IMMR; volatile sysconf5xx_t *sysconf = &immr->im_siu_conf; unsigned long reg; reg=sysconf->sc_sgpiodt2; /* Data register */ if(led_on) /* set output to 1 */ reg |= 0x02000000; else reg &= ~0x02000000; sysconf->sc_sgpiodt2=reg; /* Data register */}/**************************************************************** * Last Stage Init ****************************************************************/int last_stage_init (void){ mem_test_reloc(); init_ios(); return 0;}/**************************************************************** * Check the board ****************************************************************/#define BOARD_NAME "PATI"int checkboard (void){ unsigned char s[50]; unsigned long reg; char rev; int i; puts ("\nBoard: "); reg=in32(PLD_CONFIG_BASE+PLD_BOARD_TIMING); rev=(char)(SYSCNTR_BREV(reg)+'A'); i = getenv_r ("serial#", s, 32); if ((i == -1)) { puts ("### No HW ID - assuming " BOARD_NAME); printf(" Rev. %c\n",rev); } else { s[sizeof(BOARD_NAME)-1] = 0; printf ("%s-1 Rev %c SN: %s\n", s,rev, &s[sizeof(BOARD_NAME)]); } set_flash_vpp(1,0,0); /* set Flash VPP */ return 0;}#ifdef CFG_PCI_CON_DEVICE/************************************************************************ * PCI Communication * * Alive (Pinging): * ---------------- * PCI Host sends message ALIVE, Local acknowledges with ALIVE * * PCI_CON console over PCI: * ------------------------- * Local side: * - uses PCI9056_LOC_TO_PCI_DBELL register to signal that * data is avaible (PCIMSG_CONN) * - uses PCI9056_MAILBOX1 to send data * - uses PCI9056_MAILBOX0 to receive data * PCI side: * - uses PCI9056_PCI_TO_LOC_DBELL register to signal that * data is avaible (PCIMSG_CONN) * - uses PCI9056_MAILBOX0 to send data * - uses PCI9056_MAILBOX1 to receive data * * How it works: * Send: * - check if PCICON_TRANSMIT_REG is empty * - write data or'ed with 0x80000000 into the PCICON_TRANSMIT_REG * - write PCIMSG_CONN into the PCICON_DBELL_REG to signal a data * is waiting * Receive: * - get an interrupt via the PCICON_ACK_REG register message * PCIMSG_CONN * - write the data from the PCICON_RECEIVE_REG into the receive * buffer and if the receive buffer is not full, clear the * PCICON_RECEIVE_REG (this allows the counterpart to write more data) * - Clear the interrupt by writing 0xFFFFFFFF to the PCICON_ACK_REG * * The PCICON_RECEIVE_REG must be cleared by the routine which reads * the receive buffer if the buffer is not full any more * */#undef PCI_CON_DEBUG#ifdef PCI_CON_DEBUG#define PCI_CON_PRINTF(fmt,args...) serial_printf (fmt ,##args)#else#define PCI_CON_PRINTF(fmt,args...)#endif/********************************************************* * we work only with a receive buffer on eiter side. * Transmit buffer is free, if mailbox is cleared. * Transmit character is or'ed with 0x80000000 * PATI receive register MAILBOX0 * PATI transmit register MAILBOX1 *********************************************************/#define PCICON_RECEIVE_REG PCI9056_MAILBOX0#define PCICON_TRANSMIT_REG PCI9056_MAILBOX1#define PCICON_DBELL_REG PCI9056_LOC_TO_PCI_DBELL#define PCICON_ACK_REG PCI9056_PCI_TO_LOC_DBELL#define PCIMSG_ALIVE 0x1#define PCIMSG_CONN 0x2#define PCIMSG_DISC 0x3#define PCIMSG_CON_DATA 0x5#define PCICON_GET_REG(x) (in32(x + PCI_CONFIG_BASE))#define PCICON_SET_REG(x,y) (out32(x + PCI_CONFIG_BASE,y))#define PCICON_TX_FLAG 0x80000000#define REC_BUFFER_SIZE 0x100int recbuf[REC_BUFFER_SIZE];static int r_ptr = 0;int w_ptr;device_t pci_con_dev;int conn=0;int buff_full=0;void pci_con_put_it(const char c){ /* Test for completition */ unsigned long reg; do { reg=PCICON_GET_REG(PCICON_TRANSMIT_REG); }while(reg); reg=PCICON_TX_FLAG + c; PCICON_SET_REG(PCICON_TRANSMIT_REG,reg); PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_CON_DATA);}void pci_con_putc(const char c){ pci_con_put_it(c); if(c == '\n') pci_con_put_it('\r');}int pci_con_getc(void){ int res; int diff; while(r_ptr==(volatile int)w_ptr); res=recbuf[r_ptr++]; if(r_ptr==REC_BUFFER_SIZE) r_ptr=0; if(w_ptr<r_ptr) diff=r_ptr+REC_BUFFER_SIZE-w_ptr; else diff=r_ptr-w_ptr; if((diff<(REC_BUFFER_SIZE-4)) && buff_full) { /* clear Mail box */ buff_full=0; PCICON_SET_REG(PCICON_RECEIVE_REG,0L); } return res;}int pci_con_tstc(void){ if(r_ptr==(volatile int)w_ptr) return 0; return 1;}void pci_con_puts (const char *s){ while (*s) { pci_con_putc(*s); ++s; }}void pci_con_init (void){ w_ptr = 0; r_ptr = 0; PCICON_SET_REG(PCICON_RECEIVE_REG,0L); conn=1;}/******************************************* * IRQ routine ******************************************/int pci_dorbell_irq(void){ unsigned long reg,data; int diff; reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT); PCI_CON_PRINTF(" PCI9056_INT_CTRL_STAT = %08lX\n",reg); if(reg & (1<<20) ) { /* read doorbell */ reg=PCICON_GET_REG(PCICON_ACK_REG); switch(reg) { case PCIMSG_ALIVE: PCI_CON_PRINTF(" Alive\n"); PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_ALIVE); break; case PCIMSG_CONN: PCI_CON_PRINTF(" Conn %d",conn); w_ptr = 0; r_ptr = 0; buff_full=0; PCICON_SET_REG(PCICON_RECEIVE_REG,0L); conn=1; PCI_CON_PRINTF(" ... %d\n",conn); break; case PCIMSG_CON_DATA: data=PCICON_GET_REG(PCICON_RECEIVE_REG); recbuf[w_ptr++]=(int)(data&0xff); PCI_CON_PRINTF(" Data Console %lX, %X %d %d %X\n",data,((int)(data&0xFF)), r_ptr,w_ptr,recbuf[w_ptr-1]); if(w_ptr==REC_BUFFER_SIZE) w_ptr=0; if(w_ptr<r_ptr) diff=r_ptr+REC_BUFFER_SIZE-w_ptr; else diff=r_ptr-w_ptr; if(diff>(REC_BUFFER_SIZE-4)) buff_full=1; else /* clear Mail box */ PCICON_SET_REG(PCICON_RECEIVE_REG,0L); break; default: serial_printf(" PCI9056_PCI_TO_LOC_DBELL = %08lX\n",reg); } /* clear IRQ */ PCICON_SET_REG(PCICON_ACK_REG,~0L); } return 0;}void pci_con_connect(void){ unsigned long reg; conn=0; reg=PCICON_GET_REG(PCI9056_INT_CTRL_STAT); /* default 0x0f010180 */ reg &= 0xff000000; reg |= 0x00030000; /* enable local dorbell */ reg |= 0x00000300; /* enable PCI dorbell */ PCICON_SET_REG(PCI9056_INT_CTRL_STAT , reg); irq_install_handler (0x2, (interrupt_handler_t *) pci_dorbell_irq,NULL); memset (&pci_con_dev, 0, sizeof (pci_con_dev)); strcpy (pci_con_dev.name, "pci_con"); pci_con_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; pci_con_dev.putc = pci_con_putc; pci_con_dev.puts = pci_con_puts; pci_con_dev.getc = pci_con_getc; pci_con_dev.tstc = pci_con_tstc; device_register (&pci_con_dev); printf("PATI ready for PCI connection, type ctrl-c for exit\n"); do { udelay(10); if((volatile int)conn) break; if(ctrlc()) { irq_free_handler(0x2); return; } }while(1); console_assign(stdin,"pci_con"); console_assign(stderr,"pci_con"); console_assign(stdout,"pci_con");}void pci_con_disc(void){ console_assign(stdin,"serial"); console_assign(stderr,"serial"); console_assign(stdout,"serial"); PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_DISC); /* reconnection */ irq_free_handler(0x02); pci_con_connect();}#endif /* #ifdef CFG_PCI_CON_DEVICE *//* * Absolute environment address for linker file. */GEN_ABS(env_start, CFG_ENV_OFFSET + CFG_FLASH_BASE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -