Exemple #1
0
static int
handle_page_fault(vm_t* vm, fault_t* fault)
{
    struct device* d;

    /* See if the device is already in our address space */
    d = vm_find_device_by_ipa(vm, fault_get_address(fault));
    if (d != NULL) {
        if (d->devid == DEV_RAM) {
            DRAMFAULT("[%s] %s fault @ 0x%x from 0x%x\n", d->name,
                      (fault_is_read(fault)) ? "read" : "write",
                      fault_get_address(fault), fault_get_ctx(fault)->pc);
        } else {
            DDEVFAULT("[%s] %s fault @ 0x%x from 0x%x\n", d->name,
                      (fault_is_read(fault)) ? "read" : "write",
                      fault_get_address(fault), fault_get_ctx(fault)->pc);
        }
        return d->handle_page_fault(d, vm, fault);
    } else {
#ifdef CONFIG_ONDEMAND_DEVICE_INSTALL
        uintptr_t addr = fault_get_address(fault) & ~0xfff;
        void* mapped;
        switch (addr) {
        case 0:
            printf("VM fault on IPA 0x%08x\n", 0);
            print_fault(fault);
            return -1;
        default:
            mapped = map_vm_device(vm, addr, addr, seL4_AllRights);
            if (mapped) {
                DVM("WARNING: Blindly mapped device @ 0x%x for PC 0x%x\n",
                    fault_get_address(fault), fault_get_ctx(fault)->pc);
                restart_fault(fault);
                return 0;
            }
            mapped = map_vm_ram(vm, addr);
            if (mapped) {
                DVM("WARNING: Mapped RAM for device @ 0x%x for PC 0%x\n",
                    fault_get_address(fault), fault_get_ctx(fault)->pc);
                restart_fault(fault);
                return 0;
            }
            DVM("Unhandled fault on address 0x%x\n", (uint32_t)addr);
        }
#endif
        print_fault(fault);
        abandon_fault(fault);
        return -1;
    }
}
/**
 * Parses a free instruction
 *
 * @param cmd String representing an allocation command in the program
 * @returns Status of read and execute
 */
static status_t parse_free(char* cmd)
{
	assert(cmd != NULL);

	char var_name;
	int matched;
	var_t* var;

	// Read the command string
	errno = 0;
	matched = sscanf(cmd, "free(%c)", &var_name);

	// Check if sscanf was valid
	if (matched != 1 || errno != 0 || (var = get_var(var_name)) == NULL)
		return parse_error(cmd);

	// Ensure that the variable is in use
	if (!var->in_use) {
		print_fault(cmd, "Double free", ERROR);
		return DOUBLEFREE;
	}

	// Free variable
	buddy_free(var->mem);
	var->mem = NULL;
	var->in_use = false;

	return SUCCESS;
}
Exemple #3
0
/**
  Prototype:        void slave_check_fault(uint8_t addr)
  Input:            slave_addr: I2C address of slave
  Output:           none
  Description:      poll the I2C slave to see if any faults are occurring. if so, report
  Usage:            slave_check_fault(USBA_ADDR);
*/
void slave_check_fault(uint8_t slave_addr)
{
    //putstring0("slave_check_fault");

    if (slave_addr == CHRGR_ADDR)
    {
        usb_chrgr_regs.REG09 = i2c_slave_read(CHRGR_ADDR, 0x09);    // clear any existing fault
        usb_chrgr_regs.REG09 = i2c_slave_read(CHRGR_ADDR, 0x09);
        if (usb_chrgr_regs.REG09 != 0x00)   // check for errors
        {
            print_fault(CHRGR_ADDR, 0x09, usb_chrgr_regs.REG09);
        }
    }
    else if (slave_addr == USBA_ADDR)
    {
        i2c_slave_command(USBA_ADDR, 0x10, 0x00);                   // clear any existing fault
//        usb_porta_regs.REG10 = i2c_slave_read(USBA_ADDR, 0x10);
//        __delay_ms(5);  // give time for potential reset condition to occur
//        if (usb_porta_regs.REG10 & 0x20)   // if device has been reset, reinitialize
//                usb_port_init(USBA_ADDR);
        usb_porta_regs.REG10 = i2c_slave_read(USBA_ADDR, 0x10);
        if (usb_porta_regs.REG10 != 0x00)   // check for errors
        {
            print_fault(USBA_ADDR, 0x10, usb_porta_regs.REG10);
            clear_fault(USBA_ADDR);
        }
    }
    else if (slave_addr == USBB_ADDR)
    {
        i2c_slave_command(USBB_ADDR, 0x10, 0x00);                   // clear any existing fault
//        usb_portb_regs.REG10 = i2c_slave_read(USBB_ADDR, 0x10);
//        __delay_ms(5);  // give time for potential reset condition to occur
//        if (usb_portb_regs.REG10 & 0x20)   // if device has been reset, reinitialize
//                usb_port_init(USBB_ADDR);
        usb_portb_regs.REG10 = i2c_slave_read(USBB_ADDR, 0x10);
        if (usb_portb_regs.REG10 != 0x00)   // check for errors
        {
            print_fault(USBB_ADDR, 0x10, usb_portb_regs.REG10);
            clear_fault(USBB_ADDR);
        }
    }
    return;
}
/**
 * Parses an allocation instruction
 *
 * @param cmd String representing an allocation command in the program
 * @returns Status of read and execute
 */
static status_t parse_alloc(char* cmd)
{
	assert(cmd != NULL);
	assert(cmd[0] != '\0');

	char var_name;
	int size;
	char alter_size;
	int matched;

	errno = 0;
	matched = sscanf(cmd, "%c=alloc(%d%c)", &var_name, &size, &alter_size);

	// Error check sprintf
	if (matched == 3 && errno == 0) {
		// Check what the alter_size variable actually contains
		switch (alter_size) {
		case 'k':
		case 'K':
			size *= 1024;
		case ')':
			break;
		default:
			return parse_error(cmd);
		}
	}
	else {
		return parse_error(cmd);
	}

	// Resolve variable
	var_t* var = get_var(var_name);

	if (var == NULL)
		return parse_error(cmd);

	// Allocate variable
	var->mem = buddy_alloc(size);

	if (var->mem == NULL) {
		print_fault(cmd, "buddy_alloc returned NULL", WARNING);
		printf("Out of memory\n");
		return OUTOFMEMORY;
	}

	var->in_use = true;

	return SUCCESS;
}
Exemple #5
0
static int get_kamcmd_list(int s)
{
	struct binrpc_cmd cmd;
	int cookie;
	unsigned char reply_buf[MAX_REPLY_SIZE];
	unsigned char* msg_body;
	struct binrpc_parse_ctx in_pkt;
	int ret;

	cmd.method="system.listMethods";
	cmd.argc=0;

	cookie=gen_cookie();
	if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){
		if (ret==-1) goto error_send;
		else goto binrpc_err;
	}
	/* read reply */
	memset(&in_pkt, 0, sizeof(in_pkt));
	if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt,
					&msg_body))<0){
		goto error;
	}
	switch(in_pkt.type){
		case BINRPC_FAULT:
			if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){
				goto error;
			}
			break;
		case BINRPC_REPL:
			rpc_no=100; /* default cmd list */
			if ((rpc_array=parse_reply_body(&rpc_no, &in_pkt, msg_body,
												in_pkt.tlen))==0)
				goto error;
			break;
		default:
			fprintf(stderr, "ERROR: not a reply\n");
			goto error;
	}
	return 0;
binrpc_err:
error_send:
error:
	return -1;
}
Exemple #6
0
static int run_binrpc_cmd(int s, struct binrpc_cmd * cmd, char* fmt)
{
	int cookie;
	unsigned char reply_buf[MAX_REPLY_SIZE];
	unsigned char* msg_body;
	struct binrpc_parse_ctx in_pkt;
	int ret;

	cookie=gen_cookie();
	if ((ret=send_binrpc_cmd(s, cmd, cookie))<0){
		if (ret==-1) goto error_send;
		else goto binrpc_err;
	}
	/* read reply */
	memset(&in_pkt, 0, sizeof(in_pkt));
	if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt,
					&msg_body))<0){
		switch(ret){
			case -1:
				goto error_read;
			case -2:
				goto error_parse;
			case -3:
				goto error_cookie;
			case -4:
				goto error_toobig;
		}
		goto error;
	}
	switch(in_pkt.type){
		case BINRPC_FAULT:
			if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){
				goto error;
			}
			break;
		case BINRPC_REPL:
			if (print_body(&in_pkt, msg_body, in_pkt.tlen, fmt)<0){
				goto error;
			}
			break;
		default:
			fprintf(stderr, "ERROR: not a reply\n");
			goto error;
	}
	if (verbose) printf(".\n");
	/* normal exit */
	return 0;
binrpc_err:
	fprintf(stderr, "ERROR while building the packet: %s\n",
				binrpc_error(ret));
	goto error;
error_parse:
	fprintf(stderr, "ERROR while parsing the reply: %s\n",
				binrpc_error(binrpc_errno));
	goto error;
error_cookie:
	fprintf(stderr, "ERROR: cookie does not match\n");
	goto error;
error_toobig:
	fprintf(stderr, "ERROR: reply too big\n");
	goto error;
error_send:
	fprintf(stderr, "ERROR: send packet failed: %s (%d)\n",
			strerror(errno), errno);
	goto error;
error_read:
	fprintf(stderr, "ERROR: read reply failed: %s (%d)\n",
			strerror(errno), errno);
	goto error;
error:
	return -1;
}
Exemple #7
0
/* retrieve the counters names and group list */
static int get_counters_list(int s)
{
	struct binrpc_cmd cmd;
	int cookie;
	unsigned char reply_buf[MAX_REPLY_SIZE];
	unsigned char* msg_body;
	struct binrpc_parse_ctx in_pkt;
	struct cnt_var_grp* grp;
	struct cnt_var_grp* last_grp;
	str grp_name;
	str var_name;
	int r;
	int ret;

	cmd.method="cnt.grps_list";
	cmd.argc=0;
	if (!is_rpc_cmd(cmd.method)) goto error;

	cookie=gen_cookie();
	if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){
		if (ret==-1) goto error_send;
		else goto binrpc_err;
	}
	/* read reply */
	memset(&in_pkt, 0, sizeof(in_pkt));
	if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt,
					&msg_body))<0){
		goto error;
	}
	switch(in_pkt.type){
		case BINRPC_FAULT:
			if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){
				goto error;
			}
			break;
		case BINRPC_REPL:
			cnt_grps_no=20; /* default counter list */
			if ((cnt_grps_array=parse_reply_body(&cnt_grps_no, &in_pkt,
												msg_body, in_pkt.tlen))==0)
				goto error;
			break;
		default:
			fprintf(stderr, "ERROR: not a reply\n");
			goto error;
	}
	/* get the config groups */
	last_grp=0;
	for (r=0; r<cnt_grps_no; r++){
		grp_name.s=0; grp_name.len=0;
		if (cnt_grps_array[r].type!=BINRPC_T_STR)
			continue;
		grp_name=cnt_grps_array[r].u.strval;
		/* check for duplicates */
		for (grp=cnt_grp_lst; grp; grp=grp->next){
			if (grp->grp_name.len==grp_name.len &&
					memcmp(grp->grp_name.s, grp_name.s, grp_name.len)==0){
				break; /* found */
			}
		}
		if (grp==0){
			/* not found => create a new one  */
			grp=malloc(sizeof(*grp));
			if (grp==0) goto error_mem;
			memset(grp, 0, sizeof(*grp));
			grp->grp_name=grp_name;
			if (last_grp){
				last_grp->next=grp;
				last_grp=grp;
			}else{
				cnt_grp_lst=grp;
				last_grp=cnt_grp_lst;
			}
		}
	}
	/* gets vars per group */
	for (grp=cnt_grp_lst; grp; grp=grp->next){
		cmd.method="cnt.var_list";
		cmd.argv[0].type=BINRPC_T_STR;
		cmd.argv[0].u.strval=grp->grp_name;
		cmd.argc=1;
		if (!is_rpc_cmd(cmd.method)) goto error;
		cookie=gen_cookie();
		if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){
			if (ret==-1) goto error_send;
			else goto binrpc_err;
		}
		/* read reply */
		memset(&in_pkt, 0, sizeof(in_pkt));
		if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt,
						&msg_body))<0){
			goto error;
		}
		switch(in_pkt.type){
			case BINRPC_FAULT:
				if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){
					goto error;
				}
				break;
			case BINRPC_REPL:
				grp->cnt_vars_no=100; /* default counter list */
				if ((grp->cnt_vars_array=parse_reply_body(&grp->cnt_vars_no,
												&in_pkt, msg_body,
												in_pkt.tlen))==0)
				goto error;
				break;
			default:
				fprintf(stderr, "ERROR: not a reply\n");
				goto error;
		}
		grp->var_no = 0;
		grp->var_names=malloc(sizeof(str)*grp->cnt_vars_no);
		if (grp->var_names==0) goto error_mem;
		memset(grp->var_names, 0, sizeof(str)*grp->cnt_vars_no);
		for (r=0; r<grp->cnt_vars_no; r++) {
			if (grp->cnt_vars_array[r].type!=BINRPC_T_STR)
				continue;
			var_name=grp->cnt_vars_array[r].u.strval;
			grp->var_names[grp->var_no] = var_name;
			grp->var_no++;
		}
	}
	return 0;
binrpc_err:
error_send:
error:
error_mem:
	return -1;
}
Exemple #8
0
/* retrieve the cfg vars and group list */
static int get_cfgvars_list(int s)
{
	struct binrpc_cmd cmd;
	int cookie;
	unsigned char reply_buf[MAX_REPLY_SIZE];
	unsigned char* msg_body;
	struct binrpc_parse_ctx in_pkt;
	struct cfg_var_grp* grp;
	struct cfg_var_grp* last_grp;
	char* p;
	char* end;
	str grp_name;
	str var_name;
	int r;
	int ret;

	cmd.method="cfg.list";
	cmd.argc=0;
	if (!is_rpc_cmd(cmd.method)) goto error;

	cookie=gen_cookie();
	if ((ret=send_binrpc_cmd(s, &cmd, cookie))<0){
		if (ret==-1) goto error_send;
		else goto binrpc_err;
	}
	/* read reply */
	memset(&in_pkt, 0, sizeof(in_pkt));
	if ((ret=get_reply(s, reply_buf, MAX_REPLY_SIZE, cookie, &in_pkt,
					&msg_body))<0){
		goto error;
	}
	switch(in_pkt.type){
		case BINRPC_FAULT:
			if (print_fault(&in_pkt, msg_body, in_pkt.tlen)<0){
				goto error;
			}
			break;
		case BINRPC_REPL:
			cfg_vars_no=100; /* default cmd list */
			if ((cfg_vars_array=parse_reply_body(&cfg_vars_no, &in_pkt,
												msg_body, in_pkt.tlen))==0)
				goto error;
			break;
		default:
			fprintf(stderr, "ERROR: not a reply\n");
			goto error;
	}
	/* get the config groups */
	last_grp=0;
	for (r=0; r<cfg_vars_no; r++){
		grp_name.s=0; grp_name.len=0;
		if (cfg_vars_array[r].type!=BINRPC_T_STR)
			continue;
		grp_name.s=cfg_vars_array[r].u.strval.s;
		end=cfg_vars_array[r].u.strval.len+grp_name.s;
		/* parse <grp>: <var_name>*/
		for (p=grp_name.s; p<end; p++){
			if (*p==':'){
				grp_name.len=(int)(long)(p-grp_name.s);
				break;
			}
		}
		for (grp=cfg_grp_lst; grp; grp=grp->next){
			if (grp->grp_name.len==grp_name.len &&
					memcmp(grp->grp_name.s, grp_name.s, grp_name.len)==0){
				break; /* found */
			}
		}
		if (grp==0){
			/* not found => create a new one  */
			grp=malloc(sizeof(*grp));
			if (grp==0) goto error_mem;
			memset(grp, 0, sizeof(*grp));
			grp->grp_name=grp_name;
			if (last_grp){
				last_grp->next=grp;
				last_grp=grp;
			}else{
				cfg_grp_lst=grp;
				last_grp=cfg_grp_lst;
			}
		}
		grp->var_no++;
	}
	/* alloc the var arrays per group */
	for (grp=cfg_grp_lst; grp; grp=grp->next){
		grp->var_names=malloc(sizeof(str)*grp->var_no);
		if (grp->var_names==0) goto error_mem;
		memset(grp->var_names, 0, sizeof(str)*grp->var_no);
		grp->var_no=0;
	}
	/* reparse to get the var names per group */
	for (r=0; r<cfg_vars_no; r++){
		grp_name.s=0; grp_name.len=0;
		var_name.s=0; var_name.len=0;
		if (cfg_vars_array[r].type!=BINRPC_T_STR)
			continue;
		grp_name.s=cfg_vars_array[r].u.strval.s;
		end=cfg_vars_array[r].u.strval.len+grp_name.s;
		/* parse <grp>: <var_name>*/
		for (p=grp_name.s; p<end; p++){
			if (*p==':'){
				grp_name.len=(int)(long)(p-grp_name.s);
				p++;
				for (; p<end && *p==' '; p++);
				var_name.s=p;
				var_name.len=(int)(long)(end-p);
				if (var_name.len==0) break;
				for (grp=cfg_grp_lst; grp; grp=grp->next){
					if (grp->grp_name.len==grp_name.len &&
						memcmp(grp->grp_name.s, grp_name.s, grp_name.len)==0){
						/* add var */
						grp->var_names[grp->var_no]=var_name;
						grp->var_no++;
					}
				}
				break;
			}
		}
	}
	return 0;
binrpc_err:
error_send:
error:
error_mem:
	return -1;
}
/**
 * Throw a parsing error
 *
 * @param cmd A string representing the faulting command
 * @return Returns BADINPUT status
 */
static status_t parse_error(const char* cmd)
{
	print_fault(cmd, "Failed to parse command", ERROR);
	return BADINPUT;
}