arch/sparc/kernel/psycho_common.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/psycho_common.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/psycho_common.c
Extension
.c
Size
14613 bytes
Lines
474
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (errval != 0) {
				saw_error++;
				printk(KERN_ERR "%s: STC_ERR(%d)[wr(%d)"
				       "rd(%d)]\n",
				       pbm->name,
				       j,
				       (errval & PSYCHO_STCERR_WRITE) ? 1 : 0,
				       (errval & PSYCHO_STCERR_READ) ? 1 : 0);
			}
		}
		if (saw_error != 0) {
			u64 tagval = stc_tag_buf[i];
			u64 lineval = stc_line_buf[i];
			printk(KERN_ERR "%s: STC_TAG(%d)[PA(%016llx)VA(%08llx)"
			       "V(%d)W(%d)]\n",
			       pbm->name,
			       i,
			       ((tagval & PSYCHO_STCTAG_PPN) >> 19UL),
			       (tagval & PSYCHO_STCTAG_VPN),
			       ((tagval & PSYCHO_STCTAG_VALID) ? 1 : 0),
			       ((tagval & PSYCHO_STCTAG_WRITE) ? 1 : 0));
			printk(KERN_ERR "%s: STC_LINE(%d)[LIDX(%llx)SP(%llx)"
			       "LADDR(%llx)EP(%llx)V(%d)FOFN(%d)]\n",
			       pbm->name,
			       i,
			       ((lineval & PSYCHO_STCLINE_LINDX) >> 21UL),
			       ((lineval & PSYCHO_STCLINE_SPTR) >> 15UL),
			       ((lineval & PSYCHO_STCLINE_LADDR) >> 8UL),
			       ((lineval & PSYCHO_STCLINE_EPTR) >> 2UL),
			       ((lineval & PSYCHO_STCLINE_VALID) ? 1 : 0),
			       ((lineval & PSYCHO_STCLINE_FOFN) ? 1 : 0));
		}
	}

	spin_unlock(&stc_buf_lock);
}

#define PSYCHO_IOMMU_TAG		0xa580UL
#define PSYCHO_IOMMU_DATA		0xa600UL

static void psycho_record_iommu_tags_and_data(struct pci_pbm_info *pbm,
					      u64 *tag, u64 *data)
{
	int i;

	for (i = 0; i < 16; i++) {
		unsigned long base = pbm->controller_regs;
		unsigned long off = i * 8UL;

		tag[i] = upa_readq(base + PSYCHO_IOMMU_TAG+off);
		data[i] = upa_readq(base + PSYCHO_IOMMU_DATA+off);

		/* Now clear out the entry. */
		upa_writeq(0, base + PSYCHO_IOMMU_TAG + off);
		upa_writeq(0, base + PSYCHO_IOMMU_DATA + off);
	}
}

#define  PSYCHO_IOMMU_TAG_ERRSTS (0x3UL << 23UL)
#define  PSYCHO_IOMMU_TAG_ERR	 (0x1UL << 22UL)
#define  PSYCHO_IOMMU_TAG_WRITE	 (0x1UL << 21UL)
#define  PSYCHO_IOMMU_TAG_STREAM (0x1UL << 20UL)
#define  PSYCHO_IOMMU_TAG_SIZE	 (0x1UL << 19UL)
#define  PSYCHO_IOMMU_TAG_VPAGE	 0x7ffffULL
#define  PSYCHO_IOMMU_DATA_VALID (1UL << 30UL)
#define  PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL)
#define  PSYCHO_IOMMU_DATA_PPAGE 0xfffffffULL

static void psycho_dump_iommu_tags_and_data(struct pci_pbm_info *pbm,
					    u64 *tag, u64 *data)
{
	int i;

	for (i = 0; i < 16; i++) {
		u64 tag_val, data_val;
		const char *type_str;
		tag_val = tag[i];
		if (!(tag_val & PSYCHO_IOMMU_TAG_ERR))
			continue;

		data_val = data[i];
		switch((tag_val & PSYCHO_IOMMU_TAG_ERRSTS) >> 23UL) {
		case 0:
			type_str = "Protection Error";
			break;
		case 1:
			type_str = "Invalid Error";
			break;
		case 2:
			type_str = "TimeOut Error";

Annotation

Implementation Notes