Esempio n. 1
0
static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,
	struct unw_frame_info *info, unsigned long *reg,
	struct ia64_fpreg *freg, int rw)
{
	int result = 1;

	if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))
		return 0;

	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 (rw) {
#ifndef XEN
			char *ptr = inbuffer;

			freg->u.bits[0] = *reg;
			kgdb_hex2long(&ptr, &freg->u.bits[1]);
			*(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
				*freg;
#else
			printk("%s: %d: writing to fpreg is not supported.\n",
				   __func__, __LINE__);
#endif
			break;
		} else if (!ptregs)
			result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
				freg, rw);
		else
#ifndef XEN
			*freg =
			*(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));
#else
		    //XXX struct ia64_fpreg and struct pt_fpreg are same.
			*freg = *((struct ia64_fpreg*)(&ptregs->f6 +
										   (regnum - (IA64_FR0_REGNUM + 6))));
#endif
		break;
	default:
		if (!rw)
			result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
				freg, rw);
		else
			result = 0;
		break;
	}

	return result;
}
Esempio n. 2
0
void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
		  struct pt_regs *ptregs)
{
	unsigned long reg, size = 0, *mem = &reg;
	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;
}