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

📄 mf.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 2 页
字号:
			  unsigned size,			  unsigned count,			  MFCompleteHandler hdlr,			  void * userToken ){	struct StackElement * newElement = newStackElement();	int rc = 0;	if ( newElement == NULL )		rc = -ENOMEM;	else {		union SafeCast mine;		mine.ptr = userToken;		newElement->event.xHvLpEvent.xSubtype = 4;		newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64;		newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('A'<<0);		newElement->event.xUnion.xAllocData.xTargetLp = targetLp;		newElement->event.xUnion.xAllocData.xType = type;		newElement->event.xUnion.xAllocData.xSize = size;		newElement->event.xUnion.xAllocData.xCount = count;		newElement->hdlr = hdlr;		rc = signalEvent(newElement);	}	if ( (rc != 0) && (hdlr != NULL) )		(*hdlr)( userToken, rc );}/* * Global kernel interface to unseed and deallocate events already in * Hypervisor. */void mf_deallocateLpEvents( HvLpIndex targetLp,			    HvLpEvent_Type type,			    unsigned count,			    MFCompleteHandler hdlr,			    void * userToken ){	struct StackElement * newElement = newStackElement();	int rc = 0;	if ( newElement == NULL )		rc = -ENOMEM;	else {		union SafeCast mine;		mine.ptr = userToken;		newElement->event.xHvLpEvent.xSubtype = 5;		newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64;		newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('D'<<0);		newElement->event.xUnion.xAllocData.xTargetLp = targetLp;		newElement->event.xUnion.xAllocData.xType = type;		newElement->event.xUnion.xAllocData.xCount = count;		newElement->hdlr = hdlr;		rc = signalEvent(newElement);	}	if ( (rc != 0) && (hdlr != NULL) )		(*hdlr)( userToken, rc );}/* * Global kernel interface to tell the VSP object in the primary * partition to power this partition off. */void mf_powerOff( void ){	printk( KERN_INFO "mf.c: Down it goes...\n" );	signalCEMsg( "\x00\x00\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x00", NULL );	for (;;);}/* * Global kernel interface to tell the VSP object in the primary * partition to reboot this partition. */void mf_reboot( void ){	printk( KERN_INFO "mf.c: Preparing to bounce...\n" );	signalCEMsg( "\x00\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x00", NULL );	for (;;);}/* * Display a single word SRC onto the VSP control panel. */void mf_displaySrc( u32 word ){	u8 ce[12];	memcpy( ce, "\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x00", 12 );	ce[8] = word>>24;	ce[9] = word>>16;	ce[10] = word>>8;	ce[11] = word;	signalCEMsg( ce, NULL );}/* * Display a single word SRC of the form "PROGXXXX" on the VSP control panel. */void mf_displayProgress( u16 value ){	u8 ce[12];	u8 src[72];	memcpy( ce, "\x00\x00\x04\x4A\x00\x00\x00\x48\x00\x00\x00\x00", 12 );	memcpy( src,		"\x01\x00\x00\x01"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"\x00\x00\x00\x00"		"PROGxxxx"		"                        ",		72 );	src[6] = value>>8;	src[7] = value&255;	src[44] = "0123456789ABCDEF"[(value>>12)&15];	src[45] = "0123456789ABCDEF"[(value>>8)&15];	src[46] = "0123456789ABCDEF"[(value>>4)&15];	src[47] = "0123456789ABCDEF"[value&15];	dmaAndSignalCEMsg( ce, NULL, src, sizeof(src), 9*64*1024 );}/* * Clear the VSP control panel.  Used to "erase" an SRC that was * previously displayed. */void mf_clearSrc( void ){	signalCEMsg( "\x00\x00\x00\x4B\x00\x00\x00\x00\x00\x00\x00\x00", NULL );}/* * Initialization code here. */void mf_init( void ){	int i;    /* initialize */	spin_lock_init( &spinlock );	for ( i = 0; i < sizeof(prealloc)/sizeof(*prealloc); ++i )		free( &prealloc[i] );	HvLpEvent_registerHandler( HvLpEvent_Type_MachineFac, &hvHandler );	/* virtual continue ack */	signalCEMsg( "\x00\x00\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00", NULL );	/* initialization complete */	printk( KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities initialized\n" );	iSeries_proc_callback(&mf_proc_init);}void mf_setSide(char side){	int rc = 0;	u64 newSide = 0;	struct VspCmdData myVspCmd;	memset(&myVspCmd, 0, sizeof(myVspCmd));	if (side == 'A')		newSide = 0;	else if (side == 'B')		newSide = 1;	else if (side == 'C')		newSide = 2; 	else		newSide = 3;	myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = newSide;	myVspCmd.xCmd = 10;	rc = signalVspInstruction(&myVspCmd);}char mf_getSide(void){	char returnValue = ' ';	int rc = 0;	struct VspCmdData myVspCmd;	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.xCmd = 2;	myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = 0;	mb();	rc = signalVspInstruction(&myVspCmd);	if (rc != 0)	{		return returnValue;	} else {		if (myVspCmd.xRc == 0)		{			if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 0)				returnValue = 'A';			else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 1)				returnValue = 'B';			else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 2)				returnValue = 'C';			else				returnValue = 'D';		}	}	return returnValue;}void mf_getSrcHistory(char *buffer, int size){    /*    struct IplTypeReturnStuff returnStuff;     struct StackElement * newElement = newStackElement();     int rc = 0;     char *pages[4];     pages[0] = kmalloc(4096, GFP_ATOMIC);     pages[1] = kmalloc(4096, GFP_ATOMIC);     pages[2] = kmalloc(4096, GFP_ATOMIC);     pages[3] = kmalloc(4096, GFP_ATOMIC);     if (( newElement == NULL ) || (pages[0] == NULL) || (pages[1] == NULL) || (pages[2] == NULL) || (pages[3] == NULL))     rc = -ENOMEM;     else     {     returnStuff.xType = 0;     returnStuff.xRc = 0;     returnStuff.xDone = 0;     newElement->event.xHvLpEvent.xSubtype = 6;     newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('V'<<8)+('I'<<0);     newElement->event.xUnion.xVspCmd.xEvent = &returnStuff;     newElement->event.xUnion.xVspCmd.xCmd = 4;     newElement->event.xUnion.xVspCmd.xLpIndex = HvLpConfig_getLpIndex();     newElement->event.xUnion.xVspCmd.xRc = 0xFF;     newElement->event.xUnion.xVspCmd.xReserved1 = 0;     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[0] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[0]));     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[1] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[1]));     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[2] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[2]));     newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[3] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[3]));     mb();     rc = signalEvent(newElement);     }     if (rc != 0)     {     return;     }     else     {     while (returnStuff.xDone != 1)     {     udelay(10);     }     if (returnStuff.xRc == 0)     {     memcpy(buffer, pages[0], size);     }     }     kfree(pages[0]);     kfree(pages[1]);     kfree(pages[2]);     kfree(pages[3]);*/}void mf_setCmdLine(const char *cmdline, int size, u64 side){	struct VspCmdData myVspCmd;	int rc = 0;	dma_addr_t dma_addr = 0;	char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr);	if (page == NULL) {		printk(KERN_ERR "mf.c: couldn't allocate memory to set command line\n");		return;	}	copy_from_user(page, cmdline, size);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.xCmd = 31;	myVspCmd.xSubData.xSetKernelCmdLineIn.xToken = dma_addr;	myVspCmd.xSubData.xSetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex;	myVspCmd.xSubData.xSetKernelCmdLineIn.xSide = side;	myVspCmd.xSubData.xSetKernelCmdLineIn.xTransferLength = size;	mb();	rc = signalVspInstruction(&myVspCmd);	pci_free_consistent(iSeries_vio_dev, size, page, dma_addr);}int mf_getCmdLine(char *cmdline, int *size, u64 side){	struct VspCmdData myVspCmd;	int rc = 0;	int len = *size;	dma_addr_t dma_addr = pci_map_single(iSeries_vio_dev, cmdline, *size, PCI_DMA_FROMDEVICE);	memset(cmdline, 0, *size);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.xCmd = 33;	myVspCmd.xSubData.xGetKernelCmdLineIn.xToken = dma_addr;	myVspCmd.xSubData.xGetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex;	myVspCmd.xSubData.xGetKernelCmdLineIn.xSide = side;	myVspCmd.xSubData.xGetKernelCmdLineIn.xTransferLength = *size;	mb();	rc = signalVspInstruction(&myVspCmd);	if ( ! rc ) {		if (myVspCmd.xRc == 0)		{			len = myVspCmd.xSubData.xGetKernelCmdLineOut.xTransferLength;		}		/* else			{			memcpy(cmdline, "Bad cmdline", 11);			}		*/	}	pci_unmap_single(iSeries_vio_dev, dma_addr, *size, PCI_DMA_FROMDEVICE);	return len;}int mf_setVmlinuxChunk(const char *buffer, int size, int offset, u64 side){	struct VspCmdData myVspCmd;	int rc = 0;	dma_addr_t dma_addr = 0;	char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr);	if (page == NULL) {		printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");		return -ENOMEM;	}	copy_from_user(page, buffer, size);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.xCmd = 30;	myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr;	myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex;	myVspCmd.xSubData.xGetKernelImageIn.xSide = side;	myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset;	myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = size;	mb();	rc = signalVspInstruction(&myVspCmd);	if (rc == 0)	{		if (myVspCmd.xRc == 0)		{			rc = 0;		} else {			rc = -ENOMEM;		}	}	pci_free_consistent(iSeries_vio_dev, size, page, dma_addr);	return rc;}int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side){	struct VspCmdData myVspCmd;	int rc = 0;	int len = *size;	dma_addr_t dma_addr = pci_map_single(iSeries_vio_dev, buffer, *size, PCI_DMA_FROMDEVICE);	memset(buffer, 0, len);	memset(&myVspCmd, 0, sizeof(myVspCmd));	myVspCmd.xCmd = 32;	myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr;	myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex;	myVspCmd.xSubData.xGetKernelImageIn.xSide = side;	myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset;	myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = len;	mb();	rc = signalVspInstruction(&myVspCmd);	if (rc == 0)	{		if (myVspCmd.xRc == 0)		{			*size = myVspCmd.xSubData.xGetKernelImageOut.xTransferLength;		} else {			rc = -ENOMEM;		}	}	pci_unmap_single(iSeries_vio_dev, dma_addr, len, PCI_DMA_FROMDEVICE);	return rc;}int mf_setRtcTime(unsigned long time){	struct rtc_time tm;	to_tm(time, &tm);	return mf_setRtc( &tm );}struct RtcTimeData{	struct semaphore *xSemaphore;	struct CeMsgData xCeMsg;	int xRc;};void getRtcTimeComplete(void * token, struct CeMsgData *ceMsg){	struct RtcTimeData *rtc = (struct RtcTimeData *)token;	memcpy(&(rtc->xCeMsg), ceMsg, sizeof(rtc->xCeMsg));	rtc->xRc = 0;	up(rtc->xSemaphore);}static unsigned long lastsec = 1;int mf_getRtcTime(unsigned long *time){/*    unsigned long usec, tsec; */		u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));	u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);	int year = 1970;	int year1 = ( dataWord1 >> 24 ) & 0x000000FF;	int year2 = ( dataWord1 >> 16 ) & 0x000000FF;	int sec = ( dataWord1 >> 8 ) & 0x000000FF;	int min = dataWord1 & 0x000000FF;	int hour = ( dataWord2 >> 24 ) & 0x000000FF;	int day = ( dataWord2 >> 8 ) & 0x000000FF;	int mon = dataWord2 & 0x000000FF;	BCD_TO_BIN(sec);	BCD_TO_BIN(min);	BCD_TO_BIN(hour);	BCD_TO_BIN(day);	BCD_TO_BIN(mon);	BCD_TO_BIN(year1);	BCD_TO_BIN(year2);	year = year1 * 100 + year2;	*time = mktime(year, mon, day, hour, min, sec);	*time += ( jiffies / HZ );    	/* Now THIS is a nasty hack!	 * It ensures that the first two calls to mf_getRtcTime get different	 * answers.  That way the loop in init_time (time.c) will not think	 * the clock is stuck.	 */	if ( lastsec ) {		*time -= lastsec;		--lastsec;	}    	return 0;}int mf_getRtc( struct rtc_time * tm ){	struct CeMsgCompleteData ceComplete;	struct RtcTimeData rtcData;	int rc = 0;	DECLARE_MUTEX_LOCKED(Semaphore);	memset(&ceComplete, 0, sizeof(ceComplete));	memset(&rtcData, 0, sizeof(rtcData));	rtcData.xSemaphore = &Semaphore;	ceComplete.xHdlr = &getRtcTimeComplete;	ceComplete.xToken = (void *)&rtcData;	rc = signalCEMsg( "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", &ceComplete );	if ( rc == 0 )	{		down(&Semaphore);		if ( rtcData.xRc == 0)		{			if ( ( rtcData.xCeMsg.xCEMsg[2] == 0xa9 ) ||			     ( rtcData.xCeMsg.xCEMsg[2] == 0xaf ) ) {				/* TOD clock is not set */				tm->tm_sec = 1;				tm->tm_min = 1;				tm->tm_hour = 1;				tm->tm_mday = 10;				tm->tm_mon = 8;				tm->tm_year = 71;				mf_setRtc( tm );			}			{				u32 dataWord1 = *((u32 *)(rtcData.xCeMsg.xCEMsg+4));				u32 dataWord2 = *((u32 *)(rtcData.xCeMsg.xCEMsg+8));				u8 year = (dataWord1 >> 16 ) & 0x000000FF;				u8 sec = ( dataWord1 >> 8 ) & 0x000000FF;				u8 min = dataWord1 & 0x000000FF;				u8 hour = ( dataWord2 >> 24 ) & 0x000000FF;				u8 day = ( dataWord2 >> 8 ) & 0x000000FF;				u8 mon = dataWord2 & 0x000000FF;				BCD_TO_BIN(sec);				BCD_TO_BIN(min);				BCD_TO_BIN(hour);				BCD_TO_BIN(day);				BCD_TO_BIN(mon);				BCD_TO_BIN(year);				if ( year <= 69 )					year += 100;	    				tm->tm_sec = sec;				tm->tm_min = min;				tm->tm_hour = hour;				tm->tm_mday = day;				tm->tm_mon = mon;				tm->tm_year = year;			}		} else {			rc = rtcData.xRc;			tm->tm_sec = 0;			tm->tm_min = 0;			tm->tm_hour = 0;			tm->tm_mday = 15;			tm->tm_mon = 5;			tm->tm_year = 52;		}		tm->tm_wday = 0;		tm->tm_yday = 0;		tm->tm_isdst = 0;	}	return rc;}int mf_setRtc(struct rtc_time * tm){	char ceTime[12] = "\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00";	int rc = 0;	u8 day, mon, hour, min, sec, y1, y2;	unsigned year;    	year = 1900 + tm->tm_year;	y1 = year / 100;	y2 = year % 100;    	sec = tm->tm_sec;	min = tm->tm_min;	hour = tm->tm_hour;	day = tm->tm_mday;	mon = tm->tm_mon + 1;	    	BIN_TO_BCD(sec);	BIN_TO_BCD(min);	BIN_TO_BCD(hour);	BIN_TO_BCD(mon);	BIN_TO_BCD(day);	BIN_TO_BCD(y1);	BIN_TO_BCD(y2);	ceTime[4] = y1;	ceTime[5] = y2;	ceTime[6] = sec;	ceTime[7] = min;	ceTime[8] = hour;	ceTime[10] = day;	ceTime[11] = mon;   	rc = signalCEMsg( ceTime, NULL );	return rc;}

⌨️ 快捷键说明

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