pci_tests.c
来自「Freescale MCF5445evb 参考测试代码」· C语言 代码 · 共 2,442 行 · 第 1/5 页
C
2,442 行
/* Check for longword Alignment */ if((src&0x00000003)!= 0) { printf("Source address must be longword aligned\n"); return; } if((dest&0x00000003)!= 0) { printf("Destination address must be longword aligned\n"); return; } if((length&0x00000003)!= 0) { printf("Length must be longword aligned\n"); return; } /* Hold Tx controller at reset */ MCF_PCI_PCITER |= MCF_PCI_PCITER_RC; /* Set the Start Address */ MCF_PCI_PCITSAR = (uint32)dest; /* Set PCI Command, Max_Retries, and Max_Beats */ /* MCF_PCI_PCITTCR = MCF_PCI_PCITTCR_PCICMD(0x7); same as default out of reset */ /* Set Mode, Continuous*/ MCF_PCI_PCITER |= MCF_PCI_PCITER_CM; /* Reset FIFO */ MCF_PCI_PCITER |= MCF_PCI_PCITER_RF; for(i=0;i<100;i++); /* wait */ MCF_PCI_PCITER &= ~(0|MCF_PCI_PCITER_RF); /* Set the FIFO Alarm and Granularity Fields */ MCF_PCI_PCITFCR |= MCF_PCI_PCITFCR_GR(4); MCF_PCI_PCITFAR = MCF_PCI_PCITFAR_ALARM(32); /* Set Master Enable Bit and some error stuff*/ MCF_PCI_PCITER |= MCF_PCI_PCITER_IAE | MCF_PCI_PCITER_TAE | MCF_PCI_PCITER_ME; /* Set the Reset Controller bit Low */ MCF_PCI_PCITER &= ~(MCF_PCI_PCITER_RC); while(index < length) { /* Write Packet Size value to begin the transfer if length is < max packet size*/ if((length-index) <= PCI_MAX_PKT_SIZE) { MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(length-index); /* size of length*/ /* Stuff FIFO */ for(i=src;i<(src+(length-index));i=i+4) { MCF_PCI_PCITFDR = *(uint32*)i; index = index+4; } /* this should always be the last one, soI don't need to update the src address */ } else if((length-index) > PCI_MAX_PKT_SIZE) { MCF_PCI_PCITPSR = MCF_PCI_PCITPSR_PKTSIZE(PCI_MAX_PKT_SIZE); /* size of length*/ /* Stuff FIFO */ for(i=src;i<(src+PCI_MAX_PKT_SIZE);i=i+4) { MCF_PCI_PCITFDR = *(uint32*)i; index = index+4; } src = src +index; } else printf("packet screw-up"); }}/********************************************************************//********************************************************************/voidfiforx (int argc, char **argv){ uint32 src = 0; uint32 dest = 0; uint32 length = 0; int success, i; /* get source addres value */ if(argc > 1) { src = get_value(argv[1],&success,16); if (!success) { printf(INVALUE,argv[1]); return; } } /* get destination value */ if(argc > 2) { dest = get_value(argv[2],&success,16); if (!success) { printf(INVALUE,argv[2]); return; } } /* get length value */ if(argc > 3) { length = get_value(argv[3],&success,16); if (!success) { printf(INVALUE,argv[3]); return; } } /* Check for longword Alignment */ if((src&0x00000003)!= 0) { printf("Source address must be longword aligned\n"); return; } if((dest&0x00000003)!= 0) { printf("Destination address must be longword aligned\n"); return; } if((length&0x00000003)!= 0) { printf("Length must be longword aligned\n"); return; } printf("This command has not be implemented yet\n");}/********************************************************************//********************************************************************/voidfifostat (int argc, char **argv){ printf("Tx FIFO Registers\n"); printf("PCITPSR = 0x%08X -- Tx Packet Size Register\n",MCF_PCI_PCITPSR); printf("PCITSAR = 0x%08X -- Tx Start Address Register\n",MCF_PCI_PCITSAR); printf("PCITTCR = 0x%08X -- Tx Transaction Control Register\n",MCF_PCI_PCITTCR); printf("PCITER = 0x%08X -- Tx Enables Register\n",MCF_PCI_PCITER); printf("PCITNAR = 0x%08X -- Tx Next Address Register (RO)\n",MCF_PCI_PCITNAR); printf("PCITLWR = 0x%08X -- Tx Last Word Register (RO)\n",MCF_PCI_PCITLWR); printf("PCITDCR = 0x%08X -- Tx Done Counts Register (RO)\n",MCF_PCI_PCITDCR); printf("PCITSR = 0x%08X -- Tx Status Register (RWC)\n",MCF_PCI_PCITSR); printf("PCITFSR = 0x%08X -- Tx FIFO Status Register (RWC)\n",MCF_PCI_PCITFSR); printf("PCITFCR = 0x%08X -- Tx FIFO Control Register\n",MCF_PCI_PCITFCR); printf("PCITFAR = 0x%08X -- Tx FIFO Alarm Register (RO)\n",MCF_PCI_PCITFAR); printf("PCITFRPR = 0x%08X -- Tx FIFO Read Pointer Register (RO)\n",MCF_PCI_PCITFRPR); printf("PCITFWPR = 0x%08X -- Tx FIFO Write Pointer Register (RO) \n",MCF_PCI_PCITFWPR); printf("Rx FIFO Registers\n"); printf("PCIRPSR = 0x%08X -- Rx Packet Size Register\n",MCF_PCI_PCIRPSR); printf("PCIRSAR = 0x%08X -- Rx Start Address Register\n",MCF_PCI_PCIRSAR); printf("PCIRTCR = 0x%08X -- Rx Transaction Control Register\n",MCF_PCI_PCIRTCR); printf("PCIRER = 0x%08X -- Rx Enables Register\n",MCF_PCI_PCIRER); printf("PCIRNAR = 0x%08X -- Rx Next Address Register (RO)\n",MCF_PCI_PCIRNAR); printf("PCIRDCR = 0x%08X -- Rx Done Counts Register (RO)\n",MCF_PCI_PCIRDCR); printf("PCIRSR = 0x%08X -- Rx Status Register (RWC)\n",MCF_PCI_PCIRSR); printf("PCIRFSR = 0x%08X -- Rx FIFO Status Register (RWC)\n",MCF_PCI_PCIRFSR); printf("PCIRFCR = 0x%08X -- Rx FIFO Control Register\n",MCF_PCI_PCIRFCR); printf("PCIRFAR = 0x%08X -- Rx FIFO Alarm Register (RO)\n",MCF_PCI_PCIRFAR); printf("PCIRFRPR = 0x%08X -- Rx FIFO Read Pointer Register (RO)\n",MCF_PCI_PCIRFRPR); printf("PCIRFWPR = 0x%08X -- Rx FIFO Write Pointer Register (RO) \n",MCF_PCI_PCIRFWPR);}#endif/********************************************************************//********************************************************************/#if 0static voidget_user_input (char *userline){ char line[MAX_LINE]; int pos, ch; pos = 0; ch = (int)in_char(); while ( (ch != 0x0D /* CR */) && (ch != 0x0A /* LF/NL */) && (pos < MAX_LINE)) { switch (ch) { case 0x08: /* Backspace */ case 0x7F: /* Delete */ if (pos > 0) { pos -= 1; out_char(0x08); /* backspace */ out_char(' '); out_char(0x08); /* backspace */ } break; default: if ((pos+1) < MAX_LINE) { /* only printable characters */ if ((ch > 0x1f) && (ch < 0x80)) { line[pos++] = (char)ch; out_char((char)ch); } } break; } ch = (int)in_char(); } out_char(0x0D); /* CR */ out_char(0x0A); /* LF */ if (!pos && (strncasecmp(userline,"md",2) == 0)) { /* Allow 'md' command to be repeated */ } else { line[pos] = '\0'; strcpy(userline,line); }}/********************************************************************/static intmake_argv (char *cmdline, char *argv[]){ int argc, i, in_text; /* break cmdline into strings and argv */ /* it is permissible for argv to be NULL, in which case */ /* the purpose of this routine becomes to count args */ argc = 0; i = 0; in_text = FALSE; while (cmdline[i] != '\0') /* getline() must place 0x00 on end */ { if (((cmdline[i] == ' ') || (cmdline[i] == '\t')) ) { if (in_text) { /* end of command line argument */ cmdline[i] = '\0'; in_text = FALSE; } else { /* still looking for next argument */ } } else { /* got non-whitespace character */ if (in_text) { } else { /* start of an argument */ in_text = TRUE; if (argc < MAX_ARGS) { if (argv != NULL) argv[argc] = &cmdline[i]; argc++; } else /*return argc;*/ break; } } i++; /* proceed to next character */ } if (argv != NULL) argv[argc] = NULL; return argc;}/********************************************************************/static uint32get_value (char *s, int *success, int base){ uint32 value; char *p; value = strtoul(s,&p,base); if ((value == 0) && (p == s)) { *success = FALSE; return 0; } else { *success = TRUE; return value; }}#endif/********************************************************************/#if 0voidrun_cmd (void){ int argc; char *argv[MAX_ARGS + 1]; /* One extra for NULL terminator */ get_user_input(input); argc = make_argv(input,argv); if (argc) { int i; for (i = 0; i < NUM_CMD; i++) { if (strcasecmp(CMDTAB[i].cmd,argv[0]) == 0) { if (((argc-1) >= CMDTAB[i].min_args) && ((argc-1) <= CMDTAB[i].max_args)) { CMDTAB[i].func(argc,argv); return; } else { printf(SYNTAX,argv[0]); return; } } } printf(INVCMD,argv[0]); printf(HELPMSG); }}/********************************************************************/voidhelp (int argc, char **argv){ int index; (void)argc; (void)argv; printf("\n"); for (index = 0; index < NUM_CMD; index++) { printf(HELPFORMAT, CMDTAB[index].cmd, CMDTAB[index].description, CMDTAB[index].cmd, CMDTAB[index].syntax); } printf("\n");}#endif/********************************************************************/voidquit (int argc, char **argv){ (void)argc; (void)argv; printf("Exiting...\n"); while (1) ;}/********************************************************************/asm void asm_memcpy32(void *source, void *dest, uint32 num){ lea -20(a7),a7 movem.l d2-d6, (a7) //save off registers move.l 32(a7),d1 // num move.l 28(a7),a1 // dest move.l 24(a7),a0 // source tst.l d1 //make sure all params are non zero beq.s r_end// tst.l a0// tst.l 28(a7)// beq.s r_end// tst.l a1// tst.l 24(a7)// beq.s r_end clr.l d6 //set up increment value addi.l #16, d6 bra.s loop1a // move 4 quadlets until there are less than 4 loop1: movem.l (a0), d2-d5 movem.l d2-d5, (a1) add.l d6,a0 add.l d6,a1 subq.l #4,d1 loop1a: moveq #4, d0 cmp.l d0,d1 bge.s loop1 bra.s loop2a // move remaining quadlets loop2: move.l (a0)+,(a1)+ subq.l #1,d1loop2a: tst.l d1 bne loop2 r_end: movem.l (a7), d2-d6 //restore registers lea 20(a7), a7 rts}typedef volatile struct{ uint32 srcAddr; uint16 transferAttributes; uint16 srcAddrOff; uint32 minorByteCount; uint32 lastSrcAddrAdj; uint32 dstAddr; uint16 currentMinorLoopLink_majorLoopCount; uint16 dstAddrOff; uint32 lastDstAddrAdj_scatGathAddr; uint16 begMinorLoopLink_MajorLoopCount; uint16 controlStatus;} TCD;typedef volatile struct{ uint32 control; /* 0x00 */ uint32 errorStatus; /* 0x04 */ uint32 reserved1; /* 0x08 */ uint16 reserved2; /* 0x0c */ uint16 enableRequest; /* 0x0e */ uint32 reserved3; /* 0x10 */ uint16 reserved4; /* 0x14 */ uint16 enableErrorInterrupt; /* 0x16 */ uint8 setEnableRequest; /* 0x18 */ uint8 clearEnableRequest; /* 0x19 */ uint8 setEnableErrInterrupt; /* 0x1a */ uint8 clearEnableErrInterrupt; /**/ uint8 clearInterruptRequest; uint8 clearError; uint8 setStartBit; uint8 clearDoneStatusBit;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?