Esempio n. 1
0
unsigned
m8820x_cmmu_cpu_number()
{
	unsigned cmmu;
	u_int i;

	CMMU_LOCK;

	for (i = 0; i < 10; i++) {
		/* clear CMMU P-bus status registers */
		for (cmmu = 0; cmmu < max_cmmus; cmmu++) {
			if (CMMU_MODE(cmmu) != INST_CMMU)
				m8820x_cmmu[cmmu].cmmu_regs[CMMU_PFSR] = 0;
		}

		/* access faulting address */
		badwordaddr((vaddr_t)ILLADDRESS);

		/* check which CMMU reporting the fault  */
		for (cmmu = 0; cmmu < max_cmmus; cmmu++) {
			if (CMMU_MODE(cmmu) != INST_CMMU &&
			    CMMU_PFSR_FAULT(m8820x_cmmu[cmmu].
			      cmmu_regs[CMMU_PFSR]) != CMMU_PFSR_SUCCESS) {
				/* clean register, just in case... */
				m8820x_cmmu[cmmu].cmmu_regs[CMMU_PFSR] = 0;
				CMMU_UNLOCK;
				return cmmu >> 1;
			}
		}
	}
Esempio n. 2
0
void
m8820x_cmmu_set_cmd(u_int cmd, int flags, int cpu, int mode, vaddr_t addr)
{
	struct m8820x_cmmu *cmmu;
	int mmu, cnt;

	mmu = cpu << cmmu_shift;
	cmmu = m8820x_cmmu + mmu;

	/*
	 * We scan all CMMUs to find the matching ones and store the
	 * values there.
	 */
	for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) {
#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION
		if (cmmu->cmmu_regs == NULL)
			continue;
#endif
		if ((flags & MODE_VAL) != 0) {
			if (CMMU_MODE(mmu) != mode)
				continue;
		}
#ifdef M88200_HAS_SPLIT_ADDRESS
		if ((flags & ADDR_VAL) != 0 && cmmu->cmmu_addr_mask != 0) {
			if ((addr & cmmu->cmmu_addr_mask) != cmmu->cmmu_addr)
				continue;
		}
#endif
		cmmu->cmmu_regs[CMMU_SAR] = addr;
		cmmu->cmmu_regs[CMMU_SCR] = cmd;
	}
}
Esempio n. 3
0
void
m8820x_cmmu_set_reg(int reg, u_int val, int flags, int cpu, int mode)
{
	struct m8820x_cmmu *cmmu;
	int mmu, cnt;

	mmu = cpu << cmmu_shift;
	cmmu = m8820x_cmmu + mmu;

	/*
	 * We scan all CMMUs to find the matching ones and store the
	 * values there.
	 */
	for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) {
#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION
		if (cmmu->cmmu_regs == NULL)
			continue;
#endif
		if ((flags & MODE_VAL) != 0) {
			if (CMMU_MODE(mmu) != mode)
				continue;
		}
		cmmu->cmmu_regs[reg] = val;
	}
}
Esempio n. 4
0
/*
 * Should only be called after the calling cpus knows its cpu
 * number and main/secondary status. Should be called first
 * by the main processor, before the others are started.
*/
void
m8820x_cpu_configuration_print(int main)
{
	struct m8820x_cmmu *cmmu;
	int pid = get_cpu_pid();
	int proctype = (pid & PID_ARN) >> ARN_SHIFT;
	int procvers = (pid & PID_VN) >> VN_SHIFT;
	int reported, nmmu, mmu, cnt, cpu = cpu_number();
#ifdef M88200_HAS_SPLIT_ADDRESS
	int aline, abit, amask;
#endif

	printf("cpu%d: ", cpu);
	switch (proctype) {
	default:
		printf("unknown model arch 0x%x rev 0x%x",
		    proctype, procvers);
		break;
	case ARN_88100:
		printf("M88100 rev 0x%x", procvers);
#ifdef MULTIPROCESSOR
		if (main == 0)
			printf(", secondary");
#endif
		nmmu = 1 << cmmu_shift;
#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION
		mmu = cpu << cmmu_shift;
		cmmu = m8820x_cmmu + mmu;
		for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++)
			if (cmmu->cmmu_regs == NULL)
				nmmu--;
#endif
		printf(", %d CMMU", nmmu);

		mmu = cpu << cmmu_shift;
		cmmu = m8820x_cmmu + mmu;
		reported = 0;
		for (cnt = 1 << cmmu_shift; cnt != 0; cnt--, mmu++, cmmu++) {
			int idr, mmuid;

#ifdef M88200_HAS_ASYMMETRICAL_ASSOCIATION
			if (cmmu->cmmu_regs == NULL)
				continue;
#endif

			idr = cmmu->cmmu_regs[CMMU_IDR];
			mmuid = CMMU_TYPE(idr);

			if (reported++ % 2 == 0)
				printf("\ncpu%d: ", cpu);
			else
				printf(", ");

			switch (mmuid) {
			case M88200_ID:
				printf("M88200 (16K)");
				break;
			case M88204_ID:
				printf("M88204 (64K)");
				break;
			default:
				printf("unknown CMMU id 0x%x", mmuid);
				break;
			}
			printf(" rev 0x%x,", CMMU_VERSION(idr));
#ifdef M88200_HAS_SPLIT_ADDRESS
			/*
			 * Print address lines
			 */
			amask = cmmu->cmmu_addr_mask;
			if (amask != 0) {
				aline = 0;
				while (amask != 0) {
					abit = ff1(amask);
					if ((cmmu->cmmu_addr &
					    (1 << abit)) != 0)
						printf("%cA%02d",
						    aline != 0 ? '/' : ' ',
						    abit);
					else
						printf("%cA%02d*",
						    aline != 0 ? '/' : ' ',
						    abit);
					amask ^= 1 << abit;
				}
			} else if (cmmu_shift != 1) {
				/* unknown split scheme */
				printf(" split");
			} else
#endif
				printf(" full");
			printf(" %ccache",
			    CMMU_MODE(mmu) == INST_CMMU ? 'I' : 'D');
		}
		break;
	}
	printf("\n");

#ifndef ERRATA__XXX_USR
	{
		static int errata_warn = 0;

		if (proctype == ARN_88100 && procvers <= 10) {
			if (!errata_warn++)
				printf("WARNING: M88100 bug workaround code "
				    "not enabled.\nPlease recompile the kernel "
				    "with option ERRATA__XXX_USR !\n");
		}
	}
#endif
}