예제 #1
0
파일: machine_check.c 프로젝트: DiogoPC/xnu
void
mca_dump(void)
{
	mca_state_t	*mca_state = current_cpu_datap()->cpu_mca_state;
	uint64_t	deadline;
	unsigned int	i = 0;

	/*
	 * Capture local MCA registers to per-cpu data.
	 */
	mca_save_state(mca_state);

	/*
	 * Serialize: the first caller controls dumping MCA registers,
	 * other threads spin meantime.
	 */
	simple_lock(&mca_lock);
	if (mca_dump_state > CLEAR) {
		simple_unlock(&mca_lock);
		while (mca_dump_state == DUMPING)
			cpu_pause();
		return;
	}
	mca_dump_state = DUMPING;
	simple_unlock(&mca_lock);

	/*
	 * Wait for all other hardware threads to save their state.
	 * Or timeout.
	 */
	deadline = mach_absolute_time() + LockTimeOut;
	while (mach_absolute_time() < deadline && i < real_ncpus) {
		if (!cpu_datap(i)->cpu_mca_state->mca_is_saved) {
			cpu_pause();
			continue;
		}
		i += 1;
	}

	/*
	 * Report machine-check capabilities:
	 */
	kdb_printf(
		"Machine-check capabilities 0x%016qx:\n", ia32_mcg_cap.u64);

	mca_report_cpu_info();

	kdb_printf(
		" %d error-reporting banks\n%s%s%s", mca_error_bank_count,
		IF(mca_control_MSR_present,
		   " control MSR present\n"),
		IF(mca_threshold_status_present,
		   " threshold-based error status present\n"),
		IF(mca_cmci_present,
		   " extended corrected memory error handling present\n"));
	if (mca_extended_MSRs_present)
		kdb_printf(
			" %d extended MSRs present\n", mca_extended_MSRs_count);
 
	/*
	 * Dump all processor state:
	 */
	for (i = 0; i < real_ncpus; i++) {
		mca_state_t		*mcsp = cpu_datap(i)->cpu_mca_state;
		ia32_mcg_status_t	status;

		kdb_printf("Processor %d: ", i);
		if (mcsp == NULL ||
		    mcsp->mca_is_saved == FALSE ||
		    mcsp->mca_mcg_status.u64 == 0) {
			kdb_printf("no machine-check status reported\n");
			continue;
		}
		if (!mcsp->mca_is_valid) {
			kdb_printf("no valid machine-check state\n");
			continue;
		}
		status = mcsp->mca_mcg_status;
		kdb_printf(
			"machine-check status 0x%016qx:\n%s%s%s", status.u64,
			IF(status.bits.ripv, " restart IP valid\n"),
			IF(status.bits.eipv, " error IP valid\n"),
			IF(status.bits.mcip, " machine-check in progress\n"));

		mca_cpu_dump_error_banks(mcsp);
	}

	/*
	 * Dump any extended machine state:
	 */
	if (mca_extended_MSRs_present) {
		if (cpu_mode_is64bit())
			mca_dump_64bit_state();
		else
			mca_dump_32bit_state();
	}

	/* Update state to release any other threads. */
	mca_dump_state = DUMPED;
}
예제 #2
0
파일: machine_check.c 프로젝트: Prajna/xnu
void
mca_dump(void)
{
	ia32_mcg_status_t	status;
	mca_state_t		*mca_state = current_cpu_datap()->cpu_mca_state;

	/*
	 * Capture local MCA registers to per-cpu data.
	 */
	mca_save_state(mca_state);

	/*
	 * Serialize in case of multiple simultaneous machine-checks.
	 * Only the first caller is allowed to dump MCA registers,
	 * other threads spin meantime.
	 */
	simple_lock(&mca_lock);
	if (mca_dump_state > CLEAR) {
		simple_unlock(&mca_lock);
		while (mca_dump_state == DUMPING)
			cpu_pause();
		return;
	}
	mca_dump_state = DUMPING;
	simple_unlock(&mca_lock);

	/*
	 * Report machine-check capabilities:
	 */
	kdb_printf(
		"Machine-check capabilities (cpu %d) 0x%016qx:\n",
		cpu_number(), ia32_mcg_cap.u64);

	mca_report_cpu_info();

	kdb_printf(
		" %d error-reporting banks\n%s%s%s", mca_error_bank_count,
		IF(mca_control_MSR_present,
		   " control MSR present\n"),
		IF(mca_threshold_status_present,
		   " threshold-based error status present\n"),
		IF(mca_cmci_present,
		   " extended corrected memory error handling present\n"));
	if (mca_extended_MSRs_present)
		kdb_printf(
			" %d extended MSRs present\n", mca_extended_MSRs_count);
 
	/*
	 * Report machine-check status:
	 */
	status.u64 = rdmsr64(IA32_MCG_STATUS);
	kdb_printf(
		"Machine-check status 0x%016qx:\n%s%s%s", status.u64,
		IF(status.bits.ripv, " restart IP valid\n"),
		IF(status.bits.eipv, " error IP valid\n"),
		IF(status.bits.mcip, " machine-check in progress\n"));

	/*
	 * Dump error-reporting registers:
	 */
	mca_dump_error_banks(mca_state);

	/*
	 * Dump any extended machine state:
	 */
	if (mca_extended_MSRs_present) {
		if (cpu_mode_is64bit())
			mca_dump_64bit_state();
		else
			mca_dump_32bit_state();
	}

	/* Update state to release any other threads. */
	mca_dump_state = DUMPED;
}