Exemple #1
0
pcireg_t
ttwoga_conf_read(void *cpv, pcitag_t tag, int offset)
{
	struct ttwoga_config *tcp = cpv;
	pcireg_t *datap, data;
	int b, d, f, ba;
	paddr_t addr;
	uint64_t old_hae3;

	if ((unsigned int)offset >= PCI_CONF_SIZE)
		return (pcireg_t) -1;

	pci_decompose_tag(&tcp->tc_pc, tag, &b, &d, &f);

	addr = b ? tag : ttwoga_make_type0addr(d, f);
	if (addr == (paddr_t)-1)
		return ((pcireg_t) -1);

	TTWOGA_CONF_LOCK();

	alpha_mb();
	old_hae3 = T2GA(tcp, T2_HAE0_3) & ~HAE0_3_PCA;
	T2GA(tcp, T2_HAE0_3) =
	    old_hae3 | ((b ? 1UL : 0UL) << HAE0_3_PCA_SHIFT);
	alpha_mb();
	alpha_mb();

	datap =
	    (pcireg_t *)ALPHA_PHYS_TO_K0SEG(tcp->tc_sysmap->tsmap_conf_base |
	    addr << 5UL |		/* address shift */
	    (offset & ~0x03) << 5UL |	/* address shift */
	    0x3 << 3UL);		/* 4-byte, size shift */
	data = (pcireg_t)-1;
	if (!(ba = badaddr(datap, sizeof *datap)))
		data = *datap;

	alpha_mb();
	T2GA(tcp, T2_HAE0_3) = old_hae3;
	alpha_mb();
	alpha_mb();

	alpha_pal_draina();
	alpha_mb();
	alpha_mb();

	TTWOGA_CONF_UNLOCK();

#if 0
	printf("ttwoga_conf_read: tag 0x%lx, reg 0x%x -> 0x%x @ %p%s\n",
	    tag, offset, data, datap, ba ? " (badaddr)" : "");
#endif

	return (data);
}
int
badaddr_read(void *addr, size_t size, void *rptr)
{
	struct mchkinfo *mcp = &curcpu()->ci_mcinfo;
	long rcpt;
	int rv;

	/* Get rid of any stale machine checks that have been waiting.  */
	alpha_pal_draina();

	/* Tell the trap code to expect a machine check. */
	mcp->mc_received = 0;
	mcp->mc_expected = 1;

	/* Read from the test address, and make sure the read happens. */
	alpha_mb();
	switch (size) {
	case sizeof (u_int8_t):
		rcpt = *(volatile u_int8_t *)addr;
		break;

	case sizeof (u_int16_t):
		rcpt = *(volatile u_int16_t *)addr;
		break;

	case sizeof (u_int32_t):
		rcpt = *(volatile u_int32_t *)addr;
		break;

	case sizeof (u_int64_t):
		rcpt = *(volatile u_int64_t *)addr;
		break;

	default:
		panic("badaddr: invalid size (%ld)", size);
	}
	alpha_mb();
	alpha_mb();	/* MAGIC ON SOME SYSTEMS */

	/* Make sure we took the machine check, if we caused one. */
	alpha_pal_draina();

	/* disallow further machine checks */
	mcp->mc_expected = 0;

	rv = mcp->mc_received;
	mcp->mc_received = 0;

	/*
	 * And copy back read results (if no fault occurred).
	 */
	if (rptr && rv == 0) {
		switch (size) {
		case sizeof (u_int8_t):
			*(volatile u_int8_t *)rptr = rcpt;
			break;

		case sizeof (u_int16_t):
			*(volatile u_int16_t *)rptr = rcpt;
			break;

		case sizeof (u_int32_t):
			*(volatile u_int32_t *)rptr = rcpt;
			break;

		case sizeof (u_int64_t):
			*(volatile u_int64_t *)rptr = rcpt;
			break;
		}
	}
	/* Return non-zero (i.e. true) if it's a bad address. */
	return (rv);
}