⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pseries_lpar.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* Fill in the local HPTE with absolute rpn, avpn and flags */	lhpte.dw1.d        = 0;	lhpte.dw1.h.rpn    = arpn;	lhpte.dw1.f.flags  = hpteflags;	lhpte.dw0.d        = 0;	lhpte.dw0.h.avpn   = avpn;	lhpte.dw0.h.h      = hash;	lhpte.dw0.h.bolted = bolted;	lhpte.dw0.h.v      = 1;	/* Now fill in the actual HPTE */	/* Set CEC cookie to 0                  */	/* Large page = 0                       */	/* Zero page = 0                        */	/* I-cache Invalidate = 0               */	/* I-cache synchronize = 0              */	/* Exact = 1 - only modify exact entry  */	flags = H_EXACT;	if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))		lhpte.dw1.f.flags &= ~_PAGE_COHERENT;#if 1	__asm__ __volatile__ (		 H_ENTER_r3		 "mr	4, %1\n"		 "mr	5, %2\n"		 "mr	6, %3\n"		 "mr	7, %4\n"		 HSC		 "mr	%0, 3\n"		 : "=r" (lpar_rc)		 : "r" (flags), "r" (slot), "r" (lhpte.dw0.d), "r" (lhpte.dw1.d)		 : "r3", "r4", "r5", "r6", "r7", "cc");#else	lpar_rc =  plpar_pte_enter(flags,				   slot,				   lhpte.dw0.d,				   lhpte.dw1.d,				   &ret_hpte.dw0.dword0,				   &ret_hpte.dw1.dword1);#endif	if (lpar_rc != H_Success) {		udbg_printf("error on pte enter lapar rc = %ld\n",lpar_rc);		udbg_printf("ent: s=%lx, dw0=%lx, dw1=%lx\n", slot, lhpte.dw0.d, lhpte.dw1.d);		/* xmon_backtrace("backtrace"); */		for (;;);	}}static long hpte_find_pSeriesLP(unsigned long vpn){	union {		unsigned long d;		Hpte_dword0   h;	} hpte_dw0;	long slot;	unsigned long hash;	unsigned long i,j;	hash = hpt_hash(vpn, 0);	for ( j=0; j<2; ++j ) {		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;		for ( i=0; i<HPTES_PER_GROUP; ++i ) {			hpte_dw0.d = hpte_getword0_pSeriesLP( slot );			if ( ( hpte_dw0.h.avpn == ( vpn >> 11 ) ) &&			     ( hpte_dw0.h.v ) &&			     ( hpte_dw0.h.h == j ) ) {				/* HPTE matches */				if ( j )					slot = -slot;				return slot;			}			++slot;		}		hash = ~hash;	}	return -1;} /* * Create a pte - LPAR .  Used during initialization only. * We assume the PTE will fit in the primary PTEG. */void make_pte_LPAR(HPTE *htab,		   unsigned long va, unsigned long pa, int mode,		   unsigned long hash_mask, int large){	HPTE  local_hpte, ret_hpte;	unsigned long hash, slot, flags,lpar_rc, vpn;	if (large)		vpn = va >> 24;	else		vpn = va >> 12;	hash = hpt_hash(vpn, large);	slot = ((hash & hash_mask)*HPTES_PER_GROUP);	local_hpte.dw1.dword1 = pa | mode;	local_hpte.dw0.dword0 = 0;	local_hpte.dw0.dw0.avpn = va >> 23;	local_hpte.dw0.dw0.bolted = 1;				/* bolted */	if (large)		local_hpte.dw0.dw0.l = 1;  /* large page */	local_hpte.dw0.dw0.v = 1;	/* Set CEC cookie to 0                   */	/* Zero page = 0                         */	/* I-cache Invalidate = 0                */	/* I-cache synchronize = 0               */	/* Exact = 0 - modify any entry in group */	flags = 0;#if 1	__asm__ __volatile__ (		 H_ENTER_r3		 "mr	4, %1\n"		 "mr	5, %2\n"		 "mr	6, %3\n"		 "mr	7, %4\n"		 HSC		 "mr	%0, 3\n"		 : "=r" (lpar_rc)		 : "r" (flags), "r" (slot), "r" (local_hpte.dw0.dword0), "r" (local_hpte.dw1.dword1)		 : "r3", "r4", "r5", "r6", "r7", "cc");#else	lpar_rc =  plpar_pte_enter(flags,				   slot,				   local_hpte.dw0.dword0,				   local_hpte.dw1.dword1,				   &ret_hpte.dw0.dword0,				   &ret_hpte.dw1.dword1);#endif#if 0 /* NOTE: we explicitly do not check return status here because it is       * "normal" for early boot code to map io regions for which a partition       * has no access.  However, we will die if we actually fault on these       * "permission denied" pages.       */	if (lpar_rc != H_Success) {		/* pSeriesLP_init_early(); */		udbg_printf("flags=%lx, slot=%lx, dword0=%lx, dword1=%lx, rc=%d\n", flags, slot, local_hpte.dw0.dword0,local_hpte.dw1.dword1, lpar_rc);		BUG();	}#endif}static void tce_build_pSeriesLP(struct TceTable *tbl, long tcenum, 				unsigned long uaddr, int direction ){	u64 set_tce_rc;	union Tce tce;		PPCDBG(PPCDBG_TCE, "build_tce: uaddr = 0x%lx\n", uaddr);	PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx, tbl = 0x%lx, index=%lx\n", 	       tcenum, tbl, tbl->index);	tce.wholeTce = 0;	tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT;	tce.tceBits.readWrite = 1;	if ( direction != PCI_DMA_TODEVICE ) tce.tceBits.pciWrite = 1;	set_tce_rc = plpar_tce_put((u64)tbl->index, 				 (u64)tcenum << 12, 				 tce.wholeTce );	if(set_tce_rc) {		printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", set_tce_rc);		printk("\tindex   = 0x%lx\n", (u64)tbl->index);		printk("\ttcenum  = 0x%lx\n", (u64)tcenum);		printk("\ttce val = 0x%lx\n", tce.wholeTce );	}}static void tce_free_one_pSeriesLP(struct TceTable *tbl, long tcenum){	u64 set_tce_rc;	union Tce tce;	tce.wholeTce = 0;	set_tce_rc = plpar_tce_put((u64)tbl->index, 				 (u64)tcenum << 12,				 tce.wholeTce );	if ( set_tce_rc ) {		printk("tce_free_one_pSeriesLP: plpar_tce_put failed\n");		printk("\trc      = %ld\n", set_tce_rc);		printk("\tindex   = 0x%lx\n", (u64)tbl->index);		printk("\ttcenum  = 0x%lx\n", (u64)tcenum);		printk("\ttce val = 0x%lx\n", tce.wholeTce );	}}/* PowerPC Interrupts for lpar. *//* NOTE: this typedef is duplicated (for now) from xics.c! */typedef struct {	int (*xirr_info_get)(int cpu);	void (*xirr_info_set)(int cpu, int val);	void (*cppr_info)(int cpu, u8 val);	void (*qirr_info)(int cpu, u8 val);} xics_ops;static int pSeriesLP_xirr_info_get(int n_cpu){	unsigned long lpar_rc;	unsigned long return_value; 	lpar_rc = plpar_xirr(&return_value);	if (lpar_rc != H_Success) {		panic(" bad return code xirr - rc = %lx \n", lpar_rc); 	}	return ((int)(return_value));}static void pSeriesLP_xirr_info_set(int n_cpu, int value){	unsigned long lpar_rc;	unsigned long val64 = value & 0xffffffff;	lpar_rc = plpar_eoi(val64);	if (lpar_rc != H_Success) {		panic(" bad return code EOI - rc = %ld, value=%lx \n", lpar_rc, val64); 	}}static void pSeriesLP_cppr_info(int n_cpu, u8 value){	unsigned long lpar_rc;	lpar_rc = plpar_cppr(value);	if (lpar_rc != H_Success) {		panic(" bad return code cppr - rc = %lx \n", lpar_rc); 	}}static void pSeriesLP_qirr_info(int n_cpu , u8 value){	unsigned long lpar_rc;	lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu),value);	if (lpar_rc != H_Success) {    udbg_printf("pSeriesLP_qirr_info - plpar_ipi failed!!!!!!!! \n");		panic(" bad return code qirr -ipi  - rc = %lx \n", lpar_rc); 	}}xics_ops pSeriesLP_ops = {	pSeriesLP_xirr_info_get,	pSeriesLP_xirr_info_set,	pSeriesLP_cppr_info,	pSeriesLP_qirr_info};/* end TAI-LPAR */int vtermno;	/* virtual terminal# for udbg  */static void udbg_putcLP(unsigned char c){	char buf[16];	unsigned long rc;	if (c == '\n')		udbg_putcLP('\r');	buf[0] = c;	do {		rc = plpar_put_term_char(vtermno, 1, buf);	} while(rc == H_Busy);}/* Buffered chars getc */static long inbuflen;static long inbuf[2];	/* must be 2 longs */static int udbg_getc_pollLP(void){	/* The interface is tricky because it may return up to 16 chars.	 * We save them statically for future calls to udbg_getc().	 */	char ch, *buf = (char *)inbuf;	int i;	long rc;	if (inbuflen == 0) {		/* get some more chars. */		inbuflen = 0;		rc = plpar_get_term_char(vtermno, &inbuflen, buf);		if (rc != H_Success)			inbuflen = 0;	/* otherwise inbuflen is garbage */	}	if (inbuflen <= 0 || inbuflen > 16) {		/* Catch error case as well as other oddities (corruption) */		inbuflen = 0;		return -1;	}	ch = buf[0];	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */		buf[i-1] = buf[i];	inbuflen--;	return ch;}static unsigned char udbg_getcLP(void){	int ch;	for (;;) {		ch = udbg_getc_pollLP();		if (ch == -1) {			/* This shouldn't be needed...but... */			volatile unsigned long delay;			for (delay=0; delay < 2000000; delay++)				;		} else {			return ch;		}	}}/* This is called early in setup.c. * Use it to setup page table ppc_md stuff as well as udbg. */void pSeriesLP_init_early(void){	ppc_md.hpte_invalidate   = hpte_invalidate_pSeriesLP;	ppc_md.hpte_updatepp     = hpte_updatepp_pSeriesLP;	ppc_md.hpte_updateboltedpp  = hpte_updateboltedpp_pSeriesLP;	ppc_md.hpte_getword0     = hpte_getword0_pSeriesLP;	ppc_md.hpte_selectslot   = hpte_selectslot_pSeriesLP;	ppc_md.hpte_create_valid = hpte_create_valid_pSeriesLP;	ppc_md.hpte_find	 = hpte_find_pSeriesLP;	ppc_md.tce_build	 = tce_build_pSeriesLP;	ppc_md.tce_free_one	 = tce_free_one_pSeriesLP;#ifdef CONFIG_SMP	smp_init_pSeries();#endif	pSeries_pcibios_init_early();	/* The keyboard is not useful in the LPAR environment.	 * Leave all the interfaces NULL.	 */	if (naca->serialPortAddr) {		void *comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE);		udbg_init_uart(comport);		ppc_md.udbg_putc = udbg_putc;		ppc_md.udbg_getc = udbg_getc;		ppc_md.udbg_getc_poll = udbg_getc_poll;	} else {		/* lookup the first virtual terminal number in case we don't have a com port.		 * Zero is probably correct in case someone calls udbg before the init.		 * The property is a pair of numbers.  The first is the starting termno (the		 * one we use) and the second is the number of terminals.		 */		u32 *termno;		struct device_node *np = find_path_device("/rtas");		if (np) {			termno = (u32 *)get_property(np, "ibm,termno", 0);			if (termno)				vtermno = termno[0];		}		ppc_md.udbg_putc = udbg_putcLP;		ppc_md.udbg_getc = udbg_getcLP;		ppc_md.udbg_getc_poll = udbg_getc_pollLP;	}}/* Code for hvc_console.  Should move it back eventually. */int hvc_get_chars(int index, char *buf, int count){	unsigned long got;	if (plpar_hcall(H_GET_TERM_CHAR, index, 0, 0, 0, &got,		(unsigned long *)buf, (unsigned long *)buf+1) == H_Success) {		/*		 * Work around a HV bug where it gives us a null		 * after every \r.  -- paulus		 */		if (got > 0) {			int i;			for (i = 1; i < got; ++i) {				if (buf[i] == 0 && buf[i-1] == '\r') {					--got;					if (i < got)						memmove(&buf[i], &buf[i+1],							got - i);				}			}		}		return got;	}	return 0;}int hvc_put_chars(int index, const char *buf, int count){	unsigned long dummy;	unsigned long *lbuf = (unsigned long *) buf;	long ret;	ret = plpar_hcall(H_PUT_TERM_CHAR, index, count, lbuf[0], lbuf[1],			  &dummy, &dummy, &dummy);	if (ret == H_Success)		return count;	if (ret == H_Busy)		return 0;	return -1;}int hvc_count(int *start_termno){	u32 *termno;	struct device_node *dn;	if ((dn = find_path_device("/rtas")) != NULL) {		if ((termno = (u32 *)get_property(dn, "ibm,termno", 0)) != NULL) {			if (start_termno)				*start_termno = termno[0];			return termno[1];		}	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -