示例#1
0
void
mca_cpu_init(void)
{
	unsigned int	i;

	/*
	 * The first (boot) processor is responsible for discovering the
	 * machine check architecture present on this machine.
	 */
	if (!mca_initialized) {
		mca_get_availability();
		mca_initialized = TRUE;
		simple_lock_init(&mca_lock, 0);
	}

	if (mca_MCA_present) {

		/* Enable all MCA features */
		if (mca_control_MSR_present)
			wrmsr64(IA32_MCG_CTL, IA32_MCG_CTL_ENABLE);
	
		switch (mca_family) {
		case 0x06:
			/* Enable all but mc0 */
			for (i = 1; i < mca_error_bank_count; i++)
				wrmsr64(IA32_MCi_CTL(i),0xFFFFFFFFFFFFFFFFULL); 
			
			/* Clear all errors */
			for (i = 0; i < mca_error_bank_count; i++)
				wrmsr64(IA32_MCi_STATUS(i), 0ULL);
			break;
		case 0x0F:
			/* Enable all banks */
			for (i = 0; i < mca_error_bank_count; i++)
				wrmsr64(IA32_MCi_CTL(i),0xFFFFFFFFFFFFFFFFULL); 
			
			/* Clear all errors */
			for (i = 0; i < mca_error_bank_count; i++)
				wrmsr64(IA32_MCi_STATUS(i), 0ULL);
			break;
		}
	}

	/* Enable machine check exception handling if available */
	if (mca_MCE_present) {
		set_cr4(get_cr4()|CR4_MCE);
	}
}
示例#2
0
static void
mca_save_state(mca_state_t *mca_state)
{
	mca_mci_bank_t  *bank;
	unsigned int	i;

	assert(!ml_get_interrupts_enabled() || get_preemption_level() > 0);

	if  (mca_state == NULL)
		return;

	mca_state->mca_mcg_ctl = mca_control_MSR_present ?
					rdmsr64(IA32_MCG_CTL) : 0ULL;	
	mca_state->mca_mcg_status.u64 = rdmsr64(IA32_MCG_STATUS);

 	bank = (mca_mci_bank_t *) &mca_state->mca_error_bank[0];
	for (i = 0; i < mca_error_bank_count; i++, bank++) {
		bank->mca_mci_ctl        = rdmsr64(IA32_MCi_CTL(i));	
		bank->mca_mci_status.u64 = rdmsr64(IA32_MCi_STATUS(i));	
		if (!bank->mca_mci_status.bits.val)
			continue;
		bank->mca_mci_misc = (bank->mca_mci_status.bits.miscv)?
					rdmsr64(IA32_MCi_MISC(i)) : 0ULL;	
		bank->mca_mci_addr = (bank->mca_mci_status.bits.addrv)?
					rdmsr64(IA32_MCi_ADDR(i)) : 0ULL;	
	} 

	/*
	 * If we're the first thread with MCA state, point our package to it
	 * and don't care about races
	 */
	if (x86_package()->mca_state == NULL)
		x86_package()->mca_state = mca_state;
}
示例#3
0
static void
mca_dump_bank(mca_state_t *state, int i)
{
	mca_mci_bank_t		*bank;
	ia32_mci_status_t	status;

	bank = &state->mca_error_bank[i];
	status = bank->mca_mci_status;
	kdb_printf(
		" IA32_MC%d_STATUS(0x%x): 0x%016qx %svalid\n",
		i, IA32_MCi_STATUS(i), status.u64, IF(!status.bits.val, "in"));
	if (!status.bits.val)
		return;

	kdb_printf(
		"  MCA error code:            0x%04x\n",
		status.bits.mca_error);
	kdb_printf(
		"  Model specific error code: 0x%04x\n",
		status.bits.model_specific_error);
	if (!mca_threshold_status_present) {
		kdb_printf(
			"  Other information:         0x%08x\n",
			status.bits.other_information);
	} else {
		int	threshold = status.bits_tes_p.threshold;
		kdb_printf(
			"  Other information:         0x%08x\n"
		        "  Threshold-based status:    %s\n",
			status.bits_tes_p.other_information,
			(status.bits_tes_p.uc == 0) ?
			    mca_threshold_status[threshold] :
			    "Undefined");
	}
	if (mca_threshold_status_present &&
	    mca_sw_error_recovery_present) {
		kdb_printf(
			"  Software Error Recovery:\n%s%s",
			IF(status.bits_tes_p.ar, "   Recovery action reqd\n"),
			IF(status.bits_tes_p.s,  "   Signaling UCR error\n"));
	}
	kdb_printf(
		"  Status bits:\n%s%s%s%s%s%s",
		IF(status.bits.pcc,   "   Processor context corrupt\n"),
		IF(status.bits.addrv, "   ADDR register valid\n"),
		IF(status.bits.miscv, "   MISC register valid\n"),
		IF(status.bits.en,    "   Error enabled\n"),
		IF(status.bits.uc,    "   Uncorrected error\n"),
		IF(status.bits.over,  "   Error overflow\n"));
	if (status.bits.addrv)
		kdb_printf(
			" IA32_MC%d_ADDR(0x%x): 0x%016qx\n",
			i, IA32_MCi_ADDR(i), bank->mca_mci_addr);
	if (status.bits.miscv)
		kdb_printf(
			" IA32_MC%d_MISC(0x%x): 0x%016qx\n",
			i, IA32_MCi_MISC(i), bank->mca_mci_misc);
}
示例#4
0
static void
mca_dump_bank(mca_state_t *state, int i)
{
	mca_mci_bank_t		*bank;
	ia32_mci_status_t	status;

	bank = &state->mca_error_bank[i];
	status = bank->mca_mci_status;
	if (!status.bits.val)
		return;

	kdb_printf(" IA32_MC%d_STATUS(0x%x): 0x%016qx\n",
		i, IA32_MCi_STATUS(i), status.u64);

	if (status.bits.addrv)
		kdb_printf(" IA32_MC%d_ADDR(0x%x):   0x%016qx\n",
			i, IA32_MCi_ADDR(i), bank->mca_mci_addr);

	if (status.bits.miscv)
		kdb_printf(" IA32_MC%d_MISC(0x%x):   0x%016qx\n",
			i, IA32_MCi_MISC(i), bank->mca_mci_misc);
}
示例#5
0
static void
mca_dump_bank_mc8(mca_state_t *state, int i)
{
	mca_mci_bank_t			*bank;
	ia32_mci_status_t		status;
	struct ia32_mc8_specific	mc8;
	int				mmm;

	bank = &state->mca_error_bank[i];
	status = bank->mca_mci_status;
	mc8 = status.bits_mc8;
	mmm = MIN(mc8.memory_operation, MC8_MMM_RESERVED);

	kdb_printf(
		" IA32_MC%d_STATUS(0x%x): 0x%016qx %svalid\n",
		i, IA32_MCi_STATUS(i), status.u64, IF(!status.bits.val, "in"));
	if (!status.bits.val)
		return;

	kdb_printf(
		"  Channel number:         %d%s\n"
		"  Memory Operation:       %s\n"
		"  Machine-specific error: %s%s%s%s%s%s%s%s%s\n"
		"  COR_ERR_CNT:            %d\n",
		mc8.channel_number,
		IF(mc8.channel_number == 15, " (unknown)"),
		mc8_memory_operation[mmm],
		IF(mc8.read_ecc,            "Read ECC "),
		IF(mc8.ecc_on_a_scrub,      "ECC on scrub "),
		IF(mc8.write_parity,        "Write parity "),
		IF(mc8.redundant_memory,    "Redundant memory "),
		IF(mc8.sparing,	            "Sparing/Resilvering "),
		IF(mc8.access_out_of_range, "Access out of Range "),
		IF(mc8.rtid_out_of_range,   "RTID out of Range "),
		IF(mc8.address_parity,      "Address Parity "),
		IF(mc8.byte_enable_parity,  "Byte Enable Parity "),
		mc8.cor_err_cnt);
	kdb_printf(
		"  Status bits:\n%s%s%s%s%s%s",
		IF(status.bits.pcc,	    "   Processor context corrupt\n"),
		IF(status.bits.addrv,	    "   ADDR register valid\n"),
		IF(status.bits.miscv,	    "   MISC register valid\n"),
		IF(status.bits.en,	    "   Error enabled\n"),
		IF(status.bits.uc,	    "   Uncorrected error\n"),
		IF(status.bits.over,	    "   Error overflow\n"));
	if (status.bits.addrv)
		kdb_printf(
			" IA32_MC%d_ADDR(0x%x): 0x%016qx\n",
			i, IA32_MCi_ADDR(i), bank->mca_mci_addr);
	if (status.bits.miscv) {
		ia32_mc8_misc_t	mc8_misc;

		mc8_misc.u64 = bank->mca_mci_misc;
		kdb_printf(
			" IA32_MC%d_MISC(0x%x): 0x%016qx\n"
			"  RTID:     %d\n"
			"  DIMM:     %d\n"
			"  Channel:  %d\n"
			"  Syndrome: 0x%x\n",
			i, IA32_MCi_MISC(i), mc8_misc.u64,
			mc8_misc.bits.rtid,
			mc8_misc.bits.dimm,
			mc8_misc.bits.channel,
			(int) mc8_misc.bits.syndrome);
	}
}