예제 #1
0
void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
		  struct pt_regs *ptregs)
{
	unsigned long reg, size = 0, *mem = ®
	char nat;
	struct ia64_fpreg freg;
	int i;

	if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
	    (regnum >= (IA64_GR0_REGNUM + 4) && regnum <= (IA64_GR0_REGNUM + 7))
	    || (regnum >= (IA64_GR0_REGNUM + 16)
		&& regnum <= (IA64_GR0_REGNUM + 31))) {
		unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg, &nat, 0);
		size = sizeof(reg);
	} else
	    if ((regnum >= (IA64_GR0_REGNUM + 2)
		 && regnum <= (IA64_GR0_REGNUM + 3))
		|| (regnum >= (IA64_GR0_REGNUM + 8)
		    && regnum <= (IA64_GR0_REGNUM + 15))) {
		if (ptregs) {
			for (i = 0; i < (sizeof(gr_reg_to_ptreg_index) /
					 sizeof(gr_reg_to_ptreg_index[0])); i++)
				if (gr_reg_to_ptreg_index[0].reg == regnum) {
					reg = *((unsigned long *)
					    (((void *)ptregs) +
					    gr_reg_to_ptreg_index[i].ptregoff));
					break;
				}
		} else
			unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg,
				      &nat, 0);
		size = sizeof(reg);
	} else if (regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7))
		switch (regnum) {
		case IA64_BR0_REGNUM:
		case IA64_BR0_REGNUM + 6:
		case IA64_BR0_REGNUM + 7:
			if (ptregs) {
				for (i = 0; i < (sizeof(br_reg_to_ptreg_index) /
						 sizeof(br_reg_to_ptreg_index
							[0])); i++)
					if (br_reg_to_ptreg_index[i].reg ==
					    regnum) {
						reg = *((unsigned long *)
							(((void *)ptregs) +
							 br_reg_to_ptreg_index
							 [i].ptregoff));
						break;
					}
			} else
				unw_access_br(info, regnum - IA64_BR0_REGNUM,
					      &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_BR0_REGNUM + 1:
		case IA64_BR0_REGNUM + 2:
		case IA64_BR0_REGNUM + 3:
		case IA64_BR0_REGNUM + 4:
		case IA64_BR0_REGNUM + 5:
			unw_access_br(info, regnum - IA64_BR0_REGNUM, &reg, 0);
			size = sizeof(reg);
			break;
	} else if (regnum >= IA64_FR0_REGNUM
		   && regnum <= (IA64_FR0_REGNUM + 127))
		switch (regnum) {
		case IA64_FR0_REGNUM + 6:
		case IA64_FR0_REGNUM + 7:
		case IA64_FR0_REGNUM + 8:
		case IA64_FR0_REGNUM + 9:
		case IA64_FR0_REGNUM + 10:
		case IA64_FR0_REGNUM + 11:
		case IA64_FR0_REGNUM + 12:
			if (!ptregs)
				unw_access_fr(info, regnum - IA64_FR0_REGNUM,
					      &freg, 0);
			else {
				freg =
				    *(&ptregs->f6 +
				      (regnum - (IA64_FR0_REGNUM + 6)));
			}
			size = sizeof(freg);
			mem = (unsigned long *)&freg;
			break;
		default:
			unw_access_fr(info, regnum - IA64_FR0_REGNUM, &freg, 0);
			break;
	} else if (regnum == IA64_IP_REGNUM) {
		if (!ptregs)
			unw_get_ip(info, &reg);
		else
			reg = ptregs->cr_iip;
		size = sizeof(reg);
	} else if (regnum == IA64_CFM_REGNUM) {
		if (!ptregs)
			unw_get_cfm(info, &reg);
		else
			reg = ptregs->cr_ifs;
		size = sizeof(reg);
	} else if (regnum == IA64_PSR_REGNUM) {
		if (!ptregs && kgdb_usethread)
			ptregs = (struct pt_regs *)
			    ((unsigned long)kgdb_usethread + IA64_STK_OFFSET) -
			    1;
		if (ptregs)
			reg = ptregs->cr_ipsr;
		size = sizeof(reg);
	} else if (regnum == IA64_PR_REGNUM) {
		if (ptregs)
			reg = ptregs->pr;
		else
			unw_access_pr(info, &reg, 0);
		size = sizeof(reg);
	} else if (regnum == IA64_BSP_REGNUM) {
		unw_get_bsp(info, &reg);
		size = sizeof(reg);
	} else if (regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM)
		switch (regnum) {
		case IA64_CSD_REGNUM:
			if (ptregs)
				reg = ptregs->ar_csd;
			else
				unw_access_ar(info, UNW_AR_CSD, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_SSD_REGNUM:
			if (ptregs)
				reg = ptregs->ar_ssd;
			else
				unw_access_ar(info, UNW_AR_SSD, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_UNAT_REGNUM:
			if (ptregs)
				reg = ptregs->ar_unat;
			else
				unw_access_ar(info, UNW_AR_UNAT, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_RNAT_REGNUM:
			unw_access_ar(info, UNW_AR_RNAT, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_BSPSTORE_REGNUM:
			unw_access_ar(info, UNW_AR_BSPSTORE, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_PFS_REGNUM:
			unw_access_ar(info, UNW_AR_PFS, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_LC_REGNUM:
			unw_access_ar(info, UNW_AR_LC, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_EC_REGNUM:
			unw_access_ar(info, UNW_AR_EC, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_FPSR_REGNUM:
			if (ptregs)
				reg = ptregs->ar_fpsr;
			else
				unw_access_ar(info, UNW_AR_FPSR, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_RSC_REGNUM:
			if (ptregs)
				reg = ptregs->ar_rsc;
			else
				unw_access_ar(info, UNW_AR_RNAT, &reg, 0);
			size = sizeof(reg);
			break;
		case IA64_CCV_REGNUM:
			unw_access_ar(info, UNW_AR_CCV, &reg, 0);
			size = sizeof(reg);
			break;
		}

	if (size) {
		kgdb_mem2hex((char *)mem, outbuffer, size);
		outbuffer[size * 2] = 0;
	} else
		strcpy(outbuffer, "E0");

	return;
}
예제 #2
0
void kgdb_put_reg(char *inbuffer, char *outbuffer, int regnum,
		  struct unw_frame_info *info, struct pt_regs *ptregs)
{
	unsigned long reg;
	char nat = 0;
	struct ia64_fpreg freg;
	int i;
	char *ptr;

	ptr = inbuffer;
	kgdb_hex2long(&ptr, &reg);
	strcpy(outbuffer, "OK");

	if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
	    (regnum >= (IA64_GR0_REGNUM + 4) && regnum <= (IA64_GR0_REGNUM + 7))
	    || (regnum >= (IA64_GR0_REGNUM + 16)
		&& regnum <= (IA64_GR0_REGNUM + 31))) {
		unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg, &nat, 1);
	} else
	    if ((regnum >= (IA64_GR0_REGNUM + 2)
		 && regnum <= (IA64_GR0_REGNUM + 3))
		|| (regnum >= (IA64_GR0_REGNUM + 8)
		    && regnum <= (IA64_GR0_REGNUM + 15))) {
		for (i = 0;
		     i <
		     (sizeof(gr_reg_to_ptreg_index) /
		      sizeof(gr_reg_to_ptreg_index[0])); i++)
			if (gr_reg_to_ptreg_index[0].reg == regnum) {
				*((unsigned long *)
				  (((void *)ptregs) +
				   gr_reg_to_ptreg_index[i].ptregoff)) = reg;
				break;
			}
	} else if (regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7))
		switch (regnum) {
		case IA64_BR0_REGNUM:
		case IA64_BR0_REGNUM + 6:
		case IA64_BR0_REGNUM + 7:
			for (i = 0; i < (sizeof(br_reg_to_ptreg_index) /
					 sizeof(br_reg_to_ptreg_index[0])); i++)
				if (br_reg_to_ptreg_index[i].reg == regnum) {
					*((unsigned long *)
					  (((void *)ptregs) +
					   br_reg_to_ptreg_index[i].ptregoff)) =
			 reg;
					break;
				}
			break;
		case IA64_BR0_REGNUM + 1:
		case IA64_BR0_REGNUM + 2:
		case IA64_BR0_REGNUM + 3:
		case IA64_BR0_REGNUM + 4:
		case IA64_BR0_REGNUM + 5:
			unw_access_br(info, regnum - IA64_BR0_REGNUM, &reg, 1);
			break;
	} else if (regnum >= IA64_FR0_REGNUM
		   && regnum <= (IA64_FR0_REGNUM + 127))
		switch (regnum) {
		case IA64_FR0_REGNUM + 6:
		case IA64_FR0_REGNUM + 7:
		case IA64_FR0_REGNUM + 8:
		case IA64_FR0_REGNUM + 9:
		case IA64_FR0_REGNUM + 10:
		case IA64_FR0_REGNUM + 11:
		case IA64_FR0_REGNUM + 12:
			freg.u.bits[0] = reg;
			kgdb_hex2long(&ptr, &freg.u.bits[1]);
			*(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
			    freg;
			break;
		default:
			break;
	} else if (regnum == IA64_IP_REGNUM)
		ptregs->cr_iip = reg;
	else if (regnum == IA64_CFM_REGNUM)
		ptregs->cr_ifs = reg;
	else if (regnum == IA64_PSR_REGNUM)
		ptregs->cr_ipsr = reg;
	else if (regnum == IA64_PR_REGNUM)
		ptregs->pr = reg;
	else if (regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM)
		switch (regnum) {
		case IA64_CSD_REGNUM:
			ptregs->ar_csd = reg;
			break;
		case IA64_SSD_REGNUM:
			ptregs->ar_ssd = reg;
		case IA64_UNAT_REGNUM:
			ptregs->ar_unat = reg;
		case IA64_RNAT_REGNUM:
			unw_access_ar(info, UNW_AR_RNAT, &reg, 1);
			break;
		case IA64_BSPSTORE_REGNUM:
			unw_access_ar(info, UNW_AR_BSPSTORE, &reg, 1);
			break;
		case IA64_PFS_REGNUM:
			unw_access_ar(info, UNW_AR_PFS, &reg, 1);
			break;
		case IA64_LC_REGNUM:
			unw_access_ar(info, UNW_AR_LC, &reg, 1);
			break;
		case IA64_EC_REGNUM:
			unw_access_ar(info, UNW_AR_EC, &reg, 1);
			break;
		case IA64_FPSR_REGNUM:
			ptregs->ar_fpsr = reg;
			break;
		case IA64_RSC_REGNUM:
			ptregs->ar_rsc = reg;
			break;
		case IA64_CCV_REGNUM:
			unw_access_ar(info, UNW_AR_CCV, &reg, 1);
			break;
	} else
		strcpy(outbuffer, "E01");

	return;
}
예제 #3
0
static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,
	struct unw_frame_info *info, unsigned long *reg, int rw)
{
	int result = 0, i;

	if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))
		return 0;

	if (rw && ptregs) {
		for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
			if (ar_reg_to_ptreg_index[i].reg == regnum) {
				*((unsigned long *) (((void *)ptregs) +
				ar_reg_to_ptreg_index[i].ptregoff)) =
					*reg;
				result = 1;
				break;
			}
	} else if (ptregs) {
		for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
			if (ar_reg_to_ptreg_index[i].reg == regnum) {
				*reg = *((unsigned long *) (((void *)ptregs) +
					ar_reg_to_ptreg_index[i].ptregoff));
					result = 1;
				break;
			}
	}

	if (result)
		return result;

       result = 1;

	switch (regnum) {
	case IA64_CSD_REGNUM:
		result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);
		break;
	case IA64_SSD_REGNUM:
		result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);
		break;
	case IA64_UNAT_REGNUM:
		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
		break;
		case IA64_RNAT_REGNUM:
		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
		break;
	case IA64_BSPSTORE_REGNUM:
		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
		break;
	case IA64_PFS_REGNUM:
		result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
		break;
	case IA64_LC_REGNUM:
		result = !unw_access_ar(info, UNW_AR_LC, reg, rw);
		break;
	case IA64_EC_REGNUM:
		result = !unw_access_ar(info, UNW_AR_EC, reg, rw);
		break;
	case IA64_FPSR_REGNUM:
		result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);
		break;
	case IA64_RSC_REGNUM:
		result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);
		break;
	case IA64_CCV_REGNUM:
		result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);
		break;
	default:
		result = 0;
	}

	return result;
}