示例#1
0
static void ipu_add_wired_entry(unsigned long pid,
				unsigned long entrylo0, unsigned long entrylo1,
				unsigned long entryhi, unsigned long pagemask)
{
	unsigned long flags;
	unsigned long wired;
	unsigned long old_pagemask;
	unsigned long old_ctx;
	struct task_struct *g, *p;

	/* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */
	wired = read_c0_wired();
	if (wired) return;

	do_each_thread(g, p) {
		if (p->pid == pid )
			g_asid = p->mm->context[0];
	} while_each_thread(g, p);
	

	local_irq_save(flags);

	entrylo0 = entrylo0 >> 6;   /* PFN */
	entrylo0 |= 0x6 | (0 << 3); /* Write-through cacheable, dirty, valid */

	/* Save old context and create impossible VPN2 value */
	old_ctx = read_c0_entryhi() & 0xff;
	old_pagemask = read_c0_pagemask();
	wired = read_c0_wired();
	write_c0_wired(wired + 1);
	write_c0_index(wired);
	BARRIER;
	entryhi &= ~0xff;	/* new add, 20070906 */
	entryhi |= g_asid;	/* new add, 20070906 */
//	entryhi |= old_ctx;	/* new add, 20070906 */
	write_c0_pagemask(pagemask);
	write_c0_entryhi(entryhi);
	write_c0_entrylo0(entrylo0);
	write_c0_entrylo1(entrylo1);
	BARRIER;
	tlb_write_indexed();
	BARRIER;

	write_c0_entryhi(old_ctx);
	BARRIER;
	write_c0_pagemask(old_pagemask);
	local_flush_tlb_all();
	local_irq_restore(flags);
#if defined(DEBUG)
	printk("\nold_ctx=%03d\n", old_ctx);

	show_tlb();
#endif
}
示例#2
0
static void ipu_add_wired_entry(unsigned long pid,
				unsigned long entrylo0, unsigned long entrylo1,
				unsigned long entryhi, unsigned long pagemask)
{
	unsigned long flags;
	unsigned long wired;
	unsigned long old_pagemask;
	unsigned long old_ctx;
	struct task_struct *g, *p;

	do_each_thread(g, p) {
		if (p->pid == pid )
			g_asid = p->mm->context[0];
	} while_each_thread(g, p);
	
	local_irq_save(flags);
	/* Save old context and create impossible VPN2 value */
	old_ctx = read_c0_entryhi() & 0xff;
	old_pagemask = read_c0_pagemask();
	wired = read_c0_wired();
	write_c0_wired(wired + 1);
	write_c0_index(wired);
	BARRIER;
	entryhi &= ~0xff;	/* new add, 20070906 */
	entryhi |= g_asid;	/* new add, 20070906 */
//	entryhi |= old_ctx;	/* new add, 20070906 */
	write_c0_pagemask(pagemask);
	write_c0_entryhi(entryhi);
	write_c0_entrylo0(entrylo0);
	write_c0_entrylo1(entrylo1);
	BARRIER;
	tlb_write_indexed();
	BARRIER;

	write_c0_entryhi(old_ctx);
	BARRIER;
	write_c0_pagemask(old_pagemask);
	local_flush_tlb_all();
	local_irq_restore(flags);
#if defined(DEBUG)
	printk("\nold_ctx=%03d\n", old_ctx);

	show_tlb();
#endif
}
示例#3
0
static int ipu_read_proc (char *page, char **start, off_t off,
			  int count, int *eof, void *data)
{
	int len = 0;

	/* read as binary */
	unsigned int * pint;
	pint = (unsigned int *) (page+len);

	if ( ipu_buf_cnt >= IPU_BUF_MAX ) {	/* failed alloc mem, rturn 0 */
		printk("no free buffer.\n");
		*pint = 0;
	}
	else 
		*pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */
	len += sizeof(unsigned int);

#if defined(DEBUG)
		show_tlb();
#endif
	return len;

}
示例#4
0
static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
{
	unsigned int val ;
	int cnt,i;
	char buf[12];
	unsigned long pid, entrylo0, entrylo1, entryhi, pagemask;
#if defined(DEBUG)
	printk("ipu write count=%u\n", count);
#endif
	if (count == 41) {
		for (i=0;i<12;i++) 
			buf[i]=0;
		strncpy(buf, buffer+8*0, 8);
		pid = simple_strtoul(buf, 0, 16);
		for (i=0;i<12;i++) 
			buf[i]=0;
		strncpy(buf, buffer+8*1, 8);
		entrylo0 = simple_strtoul(buf, 0, 16);
		for (i=0;i<12;i++) 
			buf[i]=0;
		strncpy(buf, buffer+8*2, 8);
		entrylo1 = simple_strtoul(buf, 0, 16);
		for (i=0;i<12;i++) 
			buf[i]=0;
		strncpy(buf, buffer+8*3, 8);
		entryhi = simple_strtoul(buf, 0, 16);
		for (i=0;i<12;i++) 
			buf[i]=0;
		strncpy(buf, buffer+8*4, 8);
		pagemask = simple_strtoul(buf, 0, 16);
		
#if defined(DEBUG)		
		printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n", 
		       pid, entrylo0, entrylo1, entryhi, pagemask);
#endif		
		ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask);
		return 41;
	} else if ( count <= 9 ) {
		for (i=0;i<12;i++) buf[i]=0;
		strncpy(buf, buffer, 8);
		val = simple_strtoul(buf, 0, 16);
	} else if (count == 44) {
		for (i = 0; i < 12; i++) 
			buf[i] = 0;
		strncpy(buf, buffer, 10);
		pid = simple_strtoul(buf, 0, 16);

		for (i = 0; i < 12; i++) 
			buf[i] = 0;
		strncpy(buf, buffer + 11, 10);
		entryhi = simple_strtoul(buf, 0, 16);//vaddr

		for (i = 0; i < 12; i++) 
			buf[i] = 0;
		strncpy(buf, buffer + 22, 10);
		entrylo0 = simple_strtoul(buf, 0, 16);//paddr

		for (i = 0; i < 12; i++) 
			buf[i] = 0;
		strncpy(buf, buffer + 33, 10);
		pagemask = simple_strtoul(buf, 0, 16);
		pagemask = 0x3ff << 13; /* Fixed to 4MB page size */
		//pagemask = 0xfff << 13; /* Fixed to 16MB page size */

		ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask);
		return 44;
	} else if (count == 12) {
		printk("\necho release tlb > /proc/jz/ipu\n");
		ipu_del_wired_entry();
		return 12;
	} else {
		printk("ipu write count error, count=%d\n.", (unsigned int)count);
		return -1;
	}

	/* val: 1-9, page_shift,  val>= 10: ipu_buf.addr */
	if ( val == 0 ) {	/* debug, print ipu_buf info */
		for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt) 
			printk("ipu_buf[%d]: addr=0x%08x, page_shift=%d\n", 
			       cnt, ipu_buf[cnt].addr, ipu_buf[cnt].page_shift );
#if defined(DEBUG)
		show_tlb();
#endif
	}
	else if ( 0< val && val < 10 ) {
		ipu_buf_get(val);
	}
	else if ( val == 0xff ) { /* 255: free all ipu_buf */
		for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt ) {
			ipu_buf_free(ipu_buf[cnt].addr);
		}
	}
	else {			
		ipu_buf_free(val);
	}

	return count;
}
示例#5
0
static int tlb_read_proc (char *page, char **start, off_t off,
			  int count, int *eof, void *data)
{
	show_tlb();
	return 0;
}