⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfe_dmtest.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
    *  	       *  Return value:    *  	   nothing    ********************************************************************* */voiddm_bsink(void *src, int cnt){    dm_bsink_p(SBDMA_CMD_CH, phys_addr((long) src), cnt, 0);}/* Address parsing adapted from ui_examcmds. */#define ATYPE_TYPE_NONE 0#define ATYPE_TYPE_PHYS 1#define ATYPE_TYPE_VIRT 2#define ATYPE_TYPE_MASK (ATYPE_TYPE_PHYS | ATYPE_TYPE_VIRT)static intgetaddrarg(ui_cmdline_t *cmd, int arg, uint64_t *addr, int *atype){    int res;    res = -1;    if (atype) {	*atype &= ~ATYPE_TYPE_MASK;	*atype |= ATYPE_TYPE_NONE;	if (cmd_sw_isset(cmd, "-p")) {	    *atype |= ATYPE_TYPE_PHYS;	    }	else if (cmd_sw_isset(cmd, "-v")) {	    *atype |= ATYPE_TYPE_VIRT;	    }	else  {	    *atype |= ATYPE_TYPE_VIRT;   /* best default? */	    }	}    if (addr) {	char *x = cmd_getarg(cmd, arg);	*addr = 0;	if (x) {	    /* Following gdb, we Make 64-bit addresses expressed as	       8-digit numbers sign extend automagically.  Saves	       typing, but is very gross. */	    int longaddr;	    longaddr = strlen(x);	    if (memcmp(x, "0x", 2) == 0) longaddr -= 2;	    *addr = (longaddr > 8) ? (uint64_t) xtoq(x) : (uint64_t) xtoi(x);	    res = 0;	    }	}    return res;}static intgetlenarg(ui_cmdline_t *cmd, int arg, size_t *len){    int res;    res = -1;    if (len) {	char *x = cmd_getarg(cmd, arg);	*len = 0;	if (x) {	    *len = (size_t) xtoi(x);	    res = 0;	    }	}    return res;}static voidshow_rate(size_t len, uint64_t elapsed){    uint64_t rate;    char digits[4+1];    if (elapsed == 0) elapsed = 1;   /* zbclk always 0 in the simulator */    rate = ((uint64_t)len * zb_mhz * 10L)/elapsed;    sprintf(digits, "%04d", rate);    cfe_ledstr(digits);    printf("%3d.%1d MB/s\n", rate/10L, rate%10L);}static intui_cmd_zero(ui_cmdline_t *cmd, int argc, char *argv[]){    uint64_t dest;    int  dtype;    size_t len;    flags_t flags = 0;    uint64_t elapsed;    getaddrarg(cmd, 0, &dest, &dtype);    getlenarg(cmd, 1, &len);    if (cmd_sw_isset(cmd, "-u"))        flags |= DSTUNC;    else if (cmd_sw_isset(cmd, "-l2"))	flags |= L2CDEST;          if ((dtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	dest = phys_addr(dest);    if (len > 0x100000) len = 0x100000;    /* XXX single command for now */    dm_cmd_init((flags & DSTUNC) != DSTUNC);    elapsed = dm_bzero_p(SBDMA_CMD_CH, dest, len, flags);    show_rate(len, elapsed);    return 0;}static intui_cmd_sink(ui_cmdline_t *cmd, int argc, char *argv[]){    uint64_t src;    int  stype;    size_t len;    flags_t flags = 0;    uint64_t elapsed;    getaddrarg(cmd, 0, &src, &stype);    getlenarg(cmd, 1, &len);    if (cmd_sw_isset(cmd, "-u"))        flags |= SRCUNC;    else if (cmd_sw_isset(cmd, "-l2"))	flags |= L2CSRC;          if ((stype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	src = phys_addr(src);    if (len > 0x100000) len = 0x100000;    /* XXX single command for now */    dm_cmd_init((flags & SRCUNC) != SRCUNC);    elapsed = dm_bsink_p(SBDMA_CMD_CH, src, len, flags);    show_rate(len, elapsed);    return 0;}static intui_cmd_cpy(ui_cmdline_t *cmd, int argc, char *argv[]){    uint64_t src, dest;    int  stype, dtype;    size_t len;    flags_t flags = 0;    uint64_t elapsed;    getaddrarg(cmd, 0, &dest, &dtype);    getaddrarg(cmd, 1, &src, &stype);    getlenarg(cmd, 2, &len);    if (cmd_sw_isset(cmd, "-u"))        flags |= SRCUNC|DSTUNC;    else if (cmd_sw_isset(cmd, "-l2"))	flags |= L2CDEST;          if ((dtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	dest = phys_addr(dest);    if ((stype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	src = phys_addr(src);    if (len > 0x100000) len = 0x100000;    /* XXX single command for now */    dm_cmd_init((flags & (SRCUNC|DSTUNC)) != (SRCUNC|DSTUNC));    elapsed = dm_bcopy_p(SBDMA_CMD_CH, src, dest, len, flags);    show_rate(len, elapsed);    return 0;}static intui_cmd_mcpy(ui_cmdline_t *cmd, int argc, char *argv[]){    uint64_t src, dest;    int  stype, dtype;    size_t len, blksize;    flags_t flags = 0;    uint64_t elapsed;    getaddrarg(cmd, 0, &dest, &dtype);    getaddrarg(cmd, 1, &src, &stype);    getlenarg(cmd, 2, &len);    getlenarg(cmd, 3, &blksize);    if (cmd_sw_isset(cmd, "-u"))        flags |= SRCUNC|DSTUNC;    else if (cmd_sw_isset(cmd, "-l2"))	flags |= L2CDEST;          if ((dtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	dest = phys_addr(dest);    if ((stype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	src = phys_addr(src);    dm_cmd_init((flags & (SRCUNC|DSTUNC)) != (SRCUNC|DSTUNC));    if (len <= blksize)	elapsed = dm_bcopy_p(SBDMA_CMD_CH, src, dest, len, flags);    else	elapsed = dm_multibcopy_p(SBDMA_MCMD_CH, src, dest, len, blksize, flags);    show_rate(len, elapsed);    return 0;}/*  *********************************************************************    *  ui_cmd_testdm()    *      *  Test program.    *      *  Input parameters:     *  	   argc,argv    *  	       *  Return value:    *  	   0    ********************************************************************* */#ifdef _SBDMA_INTERRUPTS_#define N_SAMPLES  8typedef struct sbgendma_args_s {    int ch;    int enabled;    uint64_t src, dest;    size_t len;    flags_t flags;    uint64_t start;    uint64_t last;    uint64_t delta[N_SAMPLES];    int  index;    int toggle;    uint64_t count;} sbgendma_args_t;static voiddm_restart(sbgendma_args_t *args){    sbdmadscr_t dscr;    dm_builddescr_p(&dscr, args->dest, args->src, args->len, args->flags);    args->start = dm_startone(args->ch, &dscr);}static voiddm_interrupt_loop(void *ctx){    sbgendma_args_t *args = (sbgendma_args_t *)ctx;    sbgendma_t *d = &sbgendma_ctx[args->ch];    /*  Clear the interrupt (better in procbuffers? */    (void) DM_READCSR(d->dm_dscrbase);     dm_procbuffers(d);    if (G_DM_CUR_DSCR_DSCR_COUNT(DM_READCSR(d->dm_curdscr)) == 0) {	uint64_t start, now;	char digits[4+1];	now = zclk_get();	start = args->start;        d->dm_busy = 0;	if (args->len == 0) {	    args->enabled = 0;	    cfe_free_irq(K_INT_DM_CH_0 + args->ch, 0);	    dm_uninitctx(args->ch);	    cfe_ledstr("CFE ");	    }	else {	    dm_restart(args);	    args->delta[args->index] = zclk_elapsed(now, start);	    args->index = (args->index + 1) % N_SAMPLES;	    if (zclk_elapsed(now, args->last) > zb_hz/4) {	        int  i;	        uint64_t avg, rate;		args->last = now;		avg = 0;		for (i = 0; i < N_SAMPLES; i++)		    avg += args->delta[i];		avg /= N_SAMPLES;		rate = ((uint64_t)(args->len) * zb_mhz * 10L)/avg;		sprintf(digits, "%04d", rate);#ifdef _SENTOSA_#define WRITECSR(csr,val) *((volatile uint64_t *) (csr)) = (val)		args->toggle ^= 1;		if (args->toggle)		    WRITECSR(PHYS_TO_K1(A_GPIO_PIN_SET), M_GPIO_DEBUG_LED);		else		    WRITECSR(PHYS_TO_K1(A_GPIO_PIN_CLR), M_GPIO_DEBUG_LED);		args->count += 1;		if (args->count % (5*60*4) == 0)		    xprintf("%ld\n", args->count/(60*4));#undef WRITECSR#else		cfe_ledstr(digits);#endif		}	    }	}}static sbgendma_args_t *test_args[DM_NUM_CHANNELS] = {    NULL, NULL, NULL, NULL};static intui_cmd_testdm(ui_cmdline_t *cmd, int argc, char *argv[]){    uint64_t src, dest;    int  stype, dtype;    size_t len;    flags_t flags = 0;    sbgendma_args_t *args;    int ch = SBDMA_TEST_CH;             /* always single channel for now */    int i;    if (argc == 0) {        /* OK values for demos */        dest = 0xE000120000LL;	src  = 0x0000020000LL;	len  = 0x100000LL;	}    else {	getaddrarg(cmd, 0, &dest, &dtype);	getaddrarg(cmd, 1, &src, &stype);	getlenarg(cmd, 2, &len);	if (cmd_sw_isset(cmd, "-u"))	    flags |= SRCUNC|DSTUNC;	/* XXX Only pass 1 parts have this form of throttle.  */	if (cmd_sw_isset(cmd, "-t"))	    flags |= THROTTLE;	if ((dtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	    dest = phys_addr(dest);	if ((stype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	    src = phys_addr(src);	}    if (cmd_sw_isset(cmd, "-off"))	len = 0;    if (src < dest && (uint64_t)(src + len) > (uint64_t)dest) {        flags |= SRCDEC|DSTDEC;	dest += len - 1;	src += len - 1;	}    else {        flags |= SRCINC|DSTINC;	}    args = test_args[ch];    if (args == NULL) {	args = (sbgendma_args_t *)KMALLOC(sizeof(sbgendma_args_t), 0);	if (args == NULL)	  return -1;	args->ch = ch;	args->enabled = 0;	args->len = 0;	test_args[ch] = args;	}    args->src = src;    args->dest = dest;    args->len = len;    args->flags = flags|INTER;    args->index = 0;    for (i = 0; i < N_SAMPLES; i++)	args->delta[i] = 0;    args->toggle = 0;    args->count = 0;    dm_init();    if (!args->enabled && len != 0) {	dm_initctx(args->ch, 1, K_DM_DSCR_BASE_PRIORITY_1);      	cfe_request_irq(K_INT_DM_CH_0 + args->ch,			dm_interrupt_loop, args, 0, 0);        args->enabled = 1;	args->last = zclk_get();	dm_restart(args);	}    return 0;}#else  /* !_SBDMA_INTERRUPTS_ */static intui_cmd_testdm(ui_cmdline_t *cmd, int argc, char *argv[]){    uint64_t src, dest;    int  stype, dtype;    size_t len;    flags_t flags = 0;    uint64_t now, elapsed;    uint64_t rate;    char digits[4+1];    uint64_t last;    getaddrarg(cmd, 0, &dest, &dtype);    getaddrarg(cmd, 1, &src, &stype);    getlenarg(cmd, 2, &len);    if (cmd_sw_isset(cmd, "-u"))        flags |= SRCUNC|DSTUNC;    if ((dtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	dest = phys_addr(dest);    if ((stype & ATYPE_TYPE_MASK) == ATYPE_TYPE_VIRT)	src = phys_addr(src);    last = zclk_get();    printf("Press ENTER to stop timing\n");    dm_cmd_init((flags & (SRCUNC|DSTUNC)) != (SRCUNC|DSTUNC));    dm_initctx(SBDMA_TEST_CH, 1, K_DM_DSCR_BASE_PRIORITY_1);          do {    	elapsed = dm_bcopy_p(SBDMA_TEST_CH, src, dest, len, flags);	now = zclk_get();	if (zclk_elapsed(now, last) > zb_hz/4) {	    last = now;	    rate = ((uint64_t)len * zb_mhz * 10L)/elapsed;	    sprintf(digits, "%04d", rate);	    cfe_ledstr(digits);	    }	} while (!console_status());    dm_uninitctx(SBDMA_TEST_CH);    return 0;}#endif /* !_SBDMA_INTERRUPTS_ *//* demo stuff *//* The communication area */#define SBDMA_REMOTEP(x) ((uint64_t)(x) | 0xe000000000LL)/* Using physical address 0x10000 as the mailbox base is arbitrary but   compatible with CFE. */#define MBOX_PADDR   0x10000#define BUFFER_PADDR (MBOX_PADDR + sizeof(int))#define BUFFER_SIZE  200static int listener = 0;static voidcfe_recvdm(void *arg){    /* always use the local values */    volatile int  *mailbox = (volatile int *) PHYS_TO_K1(MBOX_PADDR);    volatile char *rx_buffer = (volatile char *) PHYS_TO_K1(BUFFER_PADDR);    if (*mailbox) {        int len;	for (len = 0; len < BUFFER_SIZE-1 && rx_buffer[len] != '\000'; len++)	    ;	rx_buffer[len] = '\000';	console_write("[", 1);	console_write((char *)rx_buffer, len);	console_write("]\r\n", 3);	*mailbox = 0;    }}static intui_cmd_talkdm(ui_cmdline_t *cmd, int argc, char *argv[]){    volatile int *mailbox;    char tx_buffer[BUFFER_SIZE];    int  tx_len;    uint64_t src, dst;    int local = cmd_sw_isset(cmd, "-l");    static char prompt[] = "Enter text, exit with \"!<ENTER>\"\r\n";    if (!listener) {	*((volatile int *) PHYS_TO_K1(MBOX_PADDR)) = 0;	cfe_bg_add(cfe_recvdm, NULL);	listener = 1;	}    src = K0_TO_PHYS((long)tx_buffer);    if (local) {	mailbox = (volatile int *) PHYS_TO_K1 (MBOX_PADDR);	dst = BUFFER_PADDR;	}    else {	mailbox = (volatile int *)	  PHYS_TO_XKSEG_UNCACHED (SBDMA_REMOTEP(MBOX_PADDR));	dst = SBDMA_REMOTEP(BUFFER_PADDR);	}    dm_init();    dm_initctx(SBDMA_TALK_CH, 1, K_DM_DSCR_BASE_PRIORITY_1);#ifdef _SBDMA_INTERRUPTS_    cfe_request_irq(K_INT_DM_CH_0 + SBDMA_TALK_CH,		    dm_interrupt, &sbgendma_ctx[SBDMA_TALK_CH], 0, 0);#endif /* _SBDMA_INTERRUPTS_ */    console_write(prompt, strlen(prompt));    for (;;) {        tx_len = console_readline("", tx_buffer, BUFFER_SIZE-1);	if (tx_len == 1 && tx_buffer[0] == '!') {	    console_write("bye\r\n", 5);	    break;	    }	tx_buffer[tx_len] = '\000';        	while (*mailbox == 1)	    POLL();	dm_bcopy_p(SBDMA_TALK_CH, src, dst, tx_len+1, 0);	*mailbox = 1;	while (*mailbox == 1)	    POLL();	}#ifdef _SBDMA_INTERRUPTS_    cfe_free_irq(K_INT_DM_CH_0 + SBDMA_TALK_CH, 0);#endif    dm_uninitctx(SBDMA_TALK_CH);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -