Exemplo n.º 1
0
int enqueue_block(volatile msg_queue_move_t* src){
  if(queue_size == MOTION_QUEUE_LENGTH)
    return -1;
  uint32_t offset = (queue_head + queue_size) & MOTION_QUEUE_MASK;
  vmemcpy(&(motion_queue[offset]), src, sizeof(msg_queue_move_t));
  queue_size++;
  return MOTION_QUEUE_LENGTH - queue_size;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
	vme_bus_handle_t bus_handle;
	vme_master_handle_t handle = NULL;
	uint64_t vme_addr;
	int am, dw, flags, use_memcpy, c;
	void *phys_addr, *buffer, *addr;
	size_t nelem, size;
	int rval = 0;

	/* Set up default values
	 */
	vme_addr = 0;
	am = VME_A32SD;
	dw = VME_D8;
	flags = VME_CTL_PWEN;
	nelem = 1;
	phys_addr = NULL;
	use_memcpy = 1;
	rval = 0;

	/* Parse the argument list
	 */
	while (-1 != (c = getopt(argc, argv, "a:A:d:e:f:p:")))
		switch (c) {
		case 'a':	/* Address modifier */
			if (strtoam(optarg, &am)) {
				fprintf(stderr, "Invalid address modifier\n");
				return -1;
			}
			break;
		case 'A':	/* VMEbus address */
			vme_addr = strtoul(optarg, NULL, 0);
			break;
		case 'd':	/* VMEbus access data width */
			if (strtodw(optarg, &dw)) {
				fprintf(stderr, "Invalid access data width\n");
				return -1;
			}
			/* If a specific data width was requested, then don't
			   use memcpy. */
			use_memcpy = 0;
			break;
		case 'e':	/* Number of elements */
			nelem = strtoul(optarg, NULL, 0);
			break;
		case 'f':	/* Flags */
			if (strtoflags(optarg, &flags)) {
				fprintf(stderr, "Invalid flags\n");
				return -1;
			}
			break;
		case 'p':	/* Physical address */
			phys_addr = (void *) strtoul(optarg, NULL, 0);
			break;
		default:
			fprintf(stderr,
				"USAGE: vme_peek [-a addr_mod] [-A vme_addr]"
				"[-d dwidth][-e num_elem][-f flags]"
				"[-p phys_addr]");
			return -1;
		}

	/* Use number of elements and data width to calculate the size.
	 */
	size = nelem * dw;

	/* Initialize
	 */
	if (vme_init(&bus_handle)) {
		perror("vme_init");
		return -1;
	}

	DPRINTF("vme_addr=0x%lx\n", (unsigned long) vme_addr);
	DPRINTF("am=0x%x\n", am);
	DPRINTF("dw=0x%x\n", dw);
	DPRINTF("size=0x%x\n", size);
	DPRINTF("flags=0x%x\n", flags);
	DPRINTF("phys_addr=0x%lx\n", (unsigned long) phys_addr);

	/* Create a handle to the necessary window
	 */
	if (vme_master_window_create(bus_handle, &handle, vme_addr, am,
				     size, flags, phys_addr)) {
		perror("vme_master_window_create");
		rval = -1;
		goto error_create;
	}

	/* This is not necessary, I just put this function here to test it and
	   demonstrate it's use.
	 */
	phys_addr = vme_master_window_phys_addr(bus_handle, handle);
	if (NULL == phys_addr) {
		perror("vme_master_window_phys_addr");
	}

	DPRINTF("Window physical address = 0x%lx\n", (unsigned long) phys_addr);

	/* Map in the window
	 */
	addr = vme_master_window_map(bus_handle, handle, 0);
	if (NULL == addr) {
		perror("vme_master_window_map");
		rval = -1;
		goto error_map;
	}

	/* Create a temporary buffer to copy data into before printing it so 
	   performance measurements won't account for local I/O.
	 */
	buffer = malloc(size);
	if (NULL == buffer) {
		perror("malloc");
		rval = -1;
		goto error_malloc;
	}

	/* Do the transfer. If data width was not given at the command line,
	   then use memcpy for fast transfers. Note that this may cause the
	   output to be byte-swapped.
	 */
	if (use_memcpy) {
		memcpy(buffer, addr, size);
	} else {
		if (vmemcpy(buffer, addr, nelem, dw)) {
			perror("vmemcpy");
			rval = -1;
			goto error_transfer;
		}
	}

	/* Print data to stdout.
	 */
	if (vdump(buffer, nelem, dw)) {
		perror("vdump");
		rval = -1;
		goto error_transfer;
	}

      error_transfer:
	free(buffer);

      error_malloc:
	if (vme_master_window_unmap(bus_handle, handle)) {
		perror("vme_master_window_unmap");
		rval = -1;
	}

      error_map:
	if (vme_master_window_release(bus_handle, handle)) {
		perror("vme_master_window_release");
		rval = -1;
	}

      error_create:
	if (vme_term(bus_handle)) {
		perror("vme_term");
		return -1;
	}

	return rval;
}
Exemplo n.º 3
0
void vntick(){
  if( pvnscks != NULL ){
    static fd_set rds, wts;
    u32 i, mfd = 0;
    struct timeval tv = { 0, 0 };
    f32 curt = vcurTime();

    mfd = 0;

    for( i = 0; i < pvnconsSize; ++i ){
      if( curt - pvntimes[ i ] > vn_timeout )
        pvnremcon( i );
    }  

    FD_ZERO( &rds );
    for( i = 0; i < pvnscksSize; ++i ){
      if( pvnscks[ i ] > mfd )
        mfd = pvnscks[ i ];
#pragma warning( push )
#pragma warning( disable: 4127 )
      FD_SET( pvnscks[ i ], &rds );
#pragma warning( pop )
    }  
    if( mfd ){ 
      pvncheck( "select failed!", select( mfd + 1, &rds, NULL, NULL, &tv ), NULL, NULL );
      for( i = 0; i < pvnscksSize; ++i ){
        if( FD_ISSET( pvnscks[ i ], &rds ) ){
          SOCKET as = accept( pvnscks[ i ], NULL, NULL );
          pvncheck( "accept failed", as, NULL, NULL );
          pvnaddcon( &as, pvncbs[ i ] );
        }
      }
    }

    FD_ZERO( &rds );
    FD_ZERO( &wts );
    mfd = 0;
    for( i = 0; i < pvnconsSize; ++i ){
      if( pvncons[ i ] > mfd )
        mfd = pvncons[ i ];
#pragma warning( push )
#pragma warning( disable: 4127 )
      FD_SET( pvncons[ i ], &rds );
      FD_SET( pvncons[ i ], &wts );
#pragma warning( pop )
    }  
    if( mfd ){
      pvncheck( "select failed!", select( mfd + 1, &rds, NULL, NULL, &tv ), NULL, NULL );

      for( i = 0; i < pvnconsSize; ++i ){
        u32 qn = ( (u32*)vmem( pvnqs ) )[ i ];
        if( FD_ISSET( pvncons[ i ], &rds ) ){
          static u8 buf[ vnbufsize ];
          int ans = recv( pvncons[ i ], buf, vnbufsize - 1, 0 );
          pvncheck( "recv failed!", ans, NULL, NULL );
          if( ans == SOCKET_ERROR )
            ans = 0;
          if( !ans ){
            pvnremcon( i );
          } else{
            ans = pvnccbs[ i ]( buf, ans, pvncids[ i ], vcurTime() );
            if( !ans )
              pvnremcon( i ); 
            else if( vsize( ans ) ){
              vappend( qn, vmem( ans ), vsize( ans ) );
            }
          }
        }
        if( FD_ISSET( pvncons[ i ], &wts ) && vsize( qn ) ){
          int ans = send( pvncons[ i ], vmem( qn ), vsize( qn ), 0 );
          pvncheck( "send failed!", ans, NULL, NULL );
          if( ans == SOCKET_ERROR )
            ans = 0;
          if( (u32)ans != vsize( qn ) ){
            u32 ns = vsize( qn ) - (u32)ans;
            u8* tb = vsmalloc( ns );
            vmemcpy( tb, ((u8*)vmem( qn )) + ans, ns );
            verase( qn );
            vappend( qn, tb, ns );
            vsfree( tb );
          }else
            verase( qn );
        }
      }
    }
  } 
}
/* I/O write */
static void trace_dev_write(void *opaque, target_phys_addr_t offset, uint32_t value)
{
    trace_dev_state *s = (trace_dev_state *)opaque;

    offset -= s->base;
    switch (offset >> 2) {
    case TRACE_DEV_REG_SWITCH:  // context switch, switch to pid
        trace_switch(value);
#ifdef DEBUG
        printf("QEMU.trace: kernel, context switch %u\n", value);
#endif
        break;
    case TRACE_DEV_REG_TGID:    // save the tgid for the following fork/clone
        tgid = value;
#ifdef DEBUG
        printf("QEMU.trace: kernel, tgid %u\n", value);
#endif
        break;
    case TRACE_DEV_REG_FORK:    // fork, fork new pid
        trace_fork(tgid, value);
#ifdef DEBUG
        printf("QEMU.trace: kernel, fork %u\n", value);
#endif
        break;
    case TRACE_DEV_REG_CLONE:    // fork, clone new pid (i.e. thread)
        trace_clone(tgid, value);
#ifdef DEBUG
        printf("QEMU.trace: kernel, clone %u\n", value);
#endif
        break;
    case TRACE_DEV_REG_EXECVE_VMSTART:  // execve, vstart
        vstart = value;
        break;
    case TRACE_DEV_REG_EXECVE_VMEND:    // execve, vend
        vend = value;
        break;
    case TRACE_DEV_REG_EXECVE_OFFSET:   // execve, offset in EXE
        eoff = value;
        break;
    case TRACE_DEV_REG_EXECVE_EXEPATH:  // init exec, path of EXE
        vstrcpy(value, path, CLIENT_PAGE_SIZE);
        trace_init_exec(vstart, vend, eoff, path);
#ifdef DEBUG
        printf("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, path);
#endif
        path[0] = 0;
        break;
    case TRACE_DEV_REG_CMDLINE_LEN:     // execve, process cmdline length
        cmdlen = value;
        break;
    case TRACE_DEV_REG_CMDLINE:         // execve, process cmdline
        vmemcpy(value, arg, cmdlen);
        trace_execve(arg, cmdlen);
#ifdef DEBUG
        {
            int i;
            for (i = 0; i < cmdlen; i ++)
                if (i != cmdlen - 1 && arg[i] == 0)
                    arg[i] = ' ';
            printf("QEMU.trace: kernel, execve %s[%d]\n", arg, cmdlen);
        }
#endif
        arg[0] = 0;
        break;
    case TRACE_DEV_REG_EXIT:            // exit, exit current process with exit code
        trace_exit(value);
#ifdef DEBUG
        printf("QEMU.trace: kernel, exit %x\n", value);
#endif
        break;
    case TRACE_DEV_REG_NAME:            // record thread name
        vstrcpy(value, path, CLIENT_PAGE_SIZE);

        // Remove the trailing newline if it exists
        int len = strlen(path);
        if (path[len - 1] == '\n') {
            path[len - 1] = 0;
        }
        trace_name(path);
#ifdef DEBUG
        printf("QEMU.trace: kernel, name %s\n", path);
#endif
        break;
    case TRACE_DEV_REG_MMAP_EXEPATH:    // mmap, path of EXE, the others are same as execve
        vstrcpy(value, path, CLIENT_PAGE_SIZE);
        trace_mmap(vstart, vend, eoff, path);
#ifdef DEBUG
        printf("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, path);
#endif
        path[0] = 0;
        break;
    case TRACE_DEV_REG_INIT_PID:        // init, name the pid that starts before device registered
        pid = value;
        break;
    case TRACE_DEV_REG_INIT_NAME:       // init, the comm of the init pid
        vstrcpy(value, path, CLIENT_PAGE_SIZE);
        trace_init_name(tgid, pid, path);
#ifdef DEBUG
        printf("QEMU.trace: kernel, init name %u [%s]\n", pid, path);
#endif
        path[0] = 0;
        break;

    case TRACE_DEV_REG_DYN_SYM_ADDR:    // dynamic symbol address
        dsaddr = value;
        break;
    case TRACE_DEV_REG_DYN_SYM:         // add dynamic symbol
        vstrcpy(value, arg, CLIENT_PAGE_SIZE);
        trace_dynamic_symbol_add(dsaddr, arg);
#ifdef DEBUG
        printf("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, arg);
#endif
        arg[0] = 0;
        break;
    case TRACE_DEV_REG_REMOVE_ADDR:         // remove dynamic symbol addr
        trace_dynamic_symbol_remove(value);
#ifdef DEBUG
        printf("QEMU.trace: dynamic symbol remove %lx\n", dsaddr);
#endif
        arg[0] = 0;
        break;

    case TRACE_DEV_REG_PRINT_STR:       // print string
        vstrcpy(value, arg, CLIENT_PAGE_SIZE);
        printf("%s", arg);
        arg[0] = 0;
        break;
    case TRACE_DEV_REG_PRINT_NUM_DEC:   // print number in decimal
        printf("%d", value);
        break;
    case TRACE_DEV_REG_PRINT_NUM_HEX:   // print number in hexical
        printf("%x", value);
        break;

    case TRACE_DEV_REG_STOP_EMU:        // stop the VM execution
        // To ensure that the number of instructions executed in this
        // block is correct, we pretend that there was an exception.
        trace_exception(0);

        cpu_single_env->exception_index = EXCP_HLT;
        cpu_single_env->halted = 1;
        qemu_system_shutdown_request();
        cpu_loop_exit();
        break;

    case TRACE_DEV_REG_ENABLE:          // tracing enable: 0 = stop, 1 = start
        if (value == 1)
            start_tracing();
        else if (value == 0) {
            stop_tracing();

            // To ensure that the number of instructions executed in this
            // block is correct, we pretend that there was an exception.
            trace_exception(0);
        }
        break;

    case TRACE_DEV_REG_UNMAP_START:
        unmap_start = value;
        break;
    case TRACE_DEV_REG_UNMAP_END:
        trace_munmap(unmap_start, value);
        break;

    default:
        cpu_abort(cpu_single_env, "trace_dev_write: Bad offset %x\n", offset);
        break;
    }
}
Exemplo n.º 5
0
int main(int argc, char **argv)
{
	vme_bus_handle_t bus_handle;
	vme_slave_handle_t handle;
	uint64_t vme_addr;
	int as, dw, flags, use_memcpy, c, rval;
	void *phys_addr, *buffer, *addr;
	size_t nelem, size;
	FILE *datafile;

	/* Set up default values
	 */
	vme_addr = 0;
	as = VME_A32;
	dw = VME_D8;
	flags = VME_CTL_PWEN | VME_CTL_PREN;
	nelem = 1;
	phys_addr = NULL;
	use_memcpy = 1;
	datafile = stdin;
	rval = 0;

	/* Parse the argument list
	 */
	while (-1 != (c = getopt(argc, argv, "a:A:d:f:F:p:")))
		switch (c) {
		case 'a':	/* Address modifier */
			if (strtoas(optarg, &as)) {
				fprintf(stderr, "Invalid address space\n");
				return -1;
			}
			break;
		case 'A':	/* VMEbus address */
			vme_addr = strtoul(optarg, NULL, 0);
			break;
		case 'd':	/* VMEbus access data width */
			if (strtodw(optarg, &dw)) {
				fprintf(stderr, "Invalid access data width\n");
				return -1;
			}
			/* If a specific data width was requested, then don't
			   use memcpy. */
			use_memcpy = 0;
			break;
		case 'f':	/* Flags */
			if (strtoflags(optarg, &flags)) {
				fprintf(stderr, "Invalid flags\n");
				return -1;
			}
			break;
		case 'F':	/* Get data from a file */
			if (NULL == (datafile = fopen(optarg, "r"))) {
				perror("fopen");
				return -1;
			}
			break;
		case 'p':	/* Physical address */
			phys_addr = (void *) strtoul(optarg, NULL, 0);
			break;
		default:
			fprintf(stderr, "USAGE: vme_slave_poke [-a addr_mod]"
				"[-A vme_addr][-d dwidth][-f flags][-F file]"
				"[-p phys_addr][hexdata...]");
			return -1;
		}

	/* Get the data to be transfered
	 */
	if (argc > optind) {	/* Get argument from the command line */
		nelem = argc - optind;
		if (vconvert_hexargs(&buffer, nelem, dw, argv + optind)) {
			return -1;
		}
	} else {		/* Read data from file or stdin */
		nelem = vconvert_hexvals(&buffer, dw, datafile);
		if (0 == nelem) {
			fprintf(stderr, "No data to transfer\n");
			return -1;
		}
	}


	/* Use number of elements and data width to calculate the size.
	 */
	size = nelem * dw;

	/* Initialize
	 */
	if (vme_init(&bus_handle)) {
		perror("vme_init");
		rval = -1;
		goto error_init;
	}

	DPRINTF("vme_addr=0x%lx\n", (unsigned long) vme_addr);
	DPRINTF("as=0x%x\n", as);
	DPRINTF("dw=0x%x\n", dw);
	DPRINTF("size=0x%x\n", size);
	DPRINTF("flags=0x%x\n", flags);
	DPRINTF("phys_addr=0x%lx\n", (unsigned long) phys_addr);

	/* Create a handle to the necessary window
	 */
	if (vme_slave_window_create(bus_handle, &handle, vme_addr, as, size,
				    flags, phys_addr)) {
		perror("vme_slave_window_create");
		rval = -1;
		goto error_create;
	}

	/* This is not necessary, I just put this function here to test it and
	   demonstrate it's use.
	 */
	phys_addr = vme_slave_window_phys_addr(bus_handle, handle);
	if (NULL == phys_addr) {
		perror("vme_slave_window_phys_addr");
	}

	DPRINTF("Window physical address = 0x%lx\n", (unsigned long) phys_addr);

	/* Map in the window
	 */
	addr = vme_slave_window_map(bus_handle, handle, 0);
	if (NULL == addr) {
		perror("vme_slave_window_map");
		rval = -1;
		goto error_map;
	}

	/* If no data width is specified, the use memcpy to transfer the data.
	   This may result in byte-swapping though.
	 */
	if (use_memcpy) {
		memcpy(addr, buffer, size);
	} else {
		if (vmemcpy(addr, buffer, nelem, dw)) {
			perror("vmemcpy");
			rval = -1;
		}
	}

	if (vme_slave_window_unmap(bus_handle, handle)) {
		perror("vme_slave_window_unmap");
		rval = -1;
	}

      error_map:
	if (vme_slave_window_release(bus_handle, handle)) {
		perror("vme_slave_window_release");
		rval = -1;
	}

      error_create:
	if (vme_term(bus_handle)) {
		perror("vme_term");
		rval = -1;
	}

      error_init:
	free(buffer);

	return rval;
}
Exemplo n.º 6
0
s64int loadElfProgram(const char *path, struct Program *prog, struct VM *vm)
{
    struct VNode node;
    Elf64_Ehdr *ehdr;
    Elf64_Phdr *phdr;
    s64int ret, n;
    u64int len, i, j, size, remain;
    char *buffer;

    ret = vfsOpen(path, 0, &node);

    if (ret!=0)
        return ret;

    ehdr = (Elf64_Ehdr *)kMalloc(sizeof(Elf64_Ehdr));
    if (!ehdr)
        return -1;
    //buffer = (char*)kMallocEx(PAGE_SIZE, 1, 0);
    buffer = (char*)kMalloc(PAGE_SIZE);
    n = vfsRead(&node, sizeof(Elf64_Ehdr), ehdr);

    if ((n == sizeof(Elf64_Ehdr)) && isValidElfHeader(ehdr)) {
        prog->entry = ehdr->e_entry;
        len = ehdr->e_phentsize * ehdr->e_phnum;
        phdr = (Elf64_Phdr*)kMalloc(len);
        vfsSeek(&node, ehdr->e_phoff, SEEK_SET);
        n = vfsRead(&node, len, phdr);
        if (n==len) {
            for (i=0; i<ehdr->e_phnum; i++) {
                if (phdr[i].p_type == PT_LOAD) {
                    ret = vmAddArea(vm, phdr[i].p_vaddr, phdr[i].p_memsz,
                            VMA_TYPE_HEAP | VMA_OWNER_USER | VMA_STATUS_USED);
                    if (ret!=0) {
                        break;
                    }

                    size = phdr[i].p_filesz;
                    remain = size & 0xfff;
                    size -= remain;
                    vfsSeek(&node, phdr[i].p_offset, SEEK_SET);
                    for (j=0; j<size; j+=PAGE_SIZE) {
                        len = vfsRead(&node, PAGE_SIZE, buffer);
                        if (len!=PAGE_SIZE) {
                            ret = -1;
                            break;
                        }
                        //DBG("%x,%x",vm,currentTask->vm);
                        vmemcpy(vm, (void*)(phdr[i].p_vaddr+j), currentTask->vm, buffer, PAGE_SIZE);
                    }
                    if (remain) {
                        len = vfsRead(&node, remain, buffer);
                        if (len == remain)
                            vmemcpy(vm, (void*)(phdr[i].p_vaddr+size), currentTask->vm, buffer, remain);
                        else 
                            ret = -1;
                    }
                    if (ret!=0)
                        break;
                }
            }
        }
        // setup stack
        if (ret == 0) {
            ret = vmAddArea(vm, USER_STACK_TOP-USER_STACK_SIZE,
                    USER_STACK_SIZE, VMA_TYPE_STACK | VMA_OWNER_USER | VMA_STATUS_USED);

        }

        kFree(phdr);
    } else 
        ret = -1;

    kFree(buffer);
    kFree(ehdr);

    vfsClose(&node);

    return ret;
}