Ejemplo n.º 1
0
static VOID ConGotoHome(void)
{
	DWORD   dwWriteSize = 0;
	CHAR    chTarg      = '\r';

	//Low level output operation should be used when in interrupt context or in process
	//of OS initialization.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		__LL_Output(chTarg);
		return;
	}

	if(!Console.bInitialized)
	{
		return;
	}
	//Write string to COM interface.
	IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
		Console.hComInt,
		1,
		(LPVOID)&chTarg,
		&dwWriteSize);
	return;
}
Ejemplo n.º 2
0
//Operations of Console object.
static VOID ConPrintStr(const char* pszStr)
{
	DWORD   dwWriteSize = 0;
	DWORD   i;

	//Low level output should be used if in context or in system initialization phase.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		dwWriteSize   = strlen(pszStr);
		for(i = 0;i < dwWriteSize;i ++)
		{
			__LL_Output(pszStr[i]);
		}
		return;
	}

	if(!Console.bInitialized)
	{
		return;
	}
	//Write string to COM interface.
	IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
		Console.hComInt,
		strlen(pszStr),
		(LPVOID)pszStr,
		&dwWriteSize);
	return;
}
Ejemplo n.º 3
0
static VOID ConClearScreen(void)
{
	//Adopt low level output operation if in interrupt context or in process
	//of system initialization.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		return;
	}
	if(!Console.bInitialized)
	{
		return;
	}
	return;
}
Ejemplo n.º 4
0
/*
 * This is the entry routine for all system bus drivers,it is called by DeviceManager when
 * it is initializing.
 * This routine checks if there is(are) PCI bus(es) in system,if not,returns FALSE,else,scan
 * all PCI buses,configure all devices reside on the PCI buses,and returns TRUE.
 */
BOOL PciBusDriver(__DEVICE_MANAGER* lpDevMgr)
{
	BOOL bResult = FALSE;

	BUG_ON(NULL == lpDevMgr);
	/* Only available in process of system initialization. */
	BUG_ON(!IN_SYSINITIALIZATION());

	/* Probe if there is PCI bus present. */
	bResult = PciBusProbe();
	if (!bResult)
	{
		/* No PCI bus presents. */
		return FALSE;
	}

	/* Scan all PCI device(s) attaching on the PCI bus system. */
	PciScanBus(lpDevMgr,NULL,0);
	return TRUE;
}
Ejemplo n.º 5
0
/* Show out bug information. */
VOID __BUG(LPSTR lpszFileName,DWORD dwLineNum)
{
	DWORD   dwFlags;
	unsigned int processor_id = __CURRENT_PROCESSOR_ID;
	__KERNEL_THREAD_OBJECT* pKernelThread = __CURRENT_KERNEL_THREAD;
	
	/* Show general bug info. */
	_hx_printk("\r\nBUG encountered[curr_processor = %d].\r\n",processor_id);
	_hx_printk("File name : %s\r\nCode Lines : %d\r\n",lpszFileName,dwLineNum);
	/* Show out specific information according current execution context. */
	if (IN_INTERRUPT())
	{
		/* Show interrupt related information. */
		_hx_printk("In interrupt context,vector:%d.\r\n", System.ucCurrInt[processor_id]);
		/* Show out interrupted kernel thread information. */
		if (pKernelThread)
		{
			_hx_printk("Interrupted kernel thread:%s\r\n", pKernelThread->KernelThreadName);
		}
	}
	else if (IN_SYSINITIALIZATION())
	{
		/* In process of system initialization. */
		_hx_printf("In process of system initialization.\r\n");
	}
	else
	{
		/* In normal thread context. */
		_hx_printf("Current kthread: %s\r\n",
			__CURRENT_KERNEL_THREAD->KernelThreadName);
	}
	/* Current CPU dive into a halt state. */
	__DISABLE_LOCAL_INTERRUPT(dwFlags);
	while (TRUE)
	{
		/* Enter halt state to save energy. */
		HaltSystem();
	}
	__RESTORE_LOCAL_INTERRUPT(dwFlags);
}
Ejemplo n.º 6
0
static VOID ConChangeLine(void)
{
	DWORD   dwWriteSize = 0;
	CHAR    chTarg      = '\n';

	//Interrupt context or OS initialization phase output.
	if(IN_INTERRUPT() || IN_SYSINITIALIZATION())
	{
		__LL_Output(chTarg);
		return;
	}

	if(!Console.bInitialized)
	{
		return;
	}
	//Write string to COM interface.
	IOManager.WriteFile((__COMMON_OBJECT*)&IOManager,
		Console.hComInt,
		1,
		(LPVOID)&chTarg,
		&dwWriteSize);
	return;
}
Ejemplo n.º 7
0
/*
 * Scans a PCI bus and all it's child buses(if exist).For each bus,use
 * one element of SystemBus array(in DeviceManager object) to record it.
 * This routine returns the largest bus number in this bus tree,if failed,
 * returns MAX_DWORD_VALUE, which is 0xFFFFFFFF currently.
 */
static DWORD PciScanBus(__DEVICE_MANAGER* lpDevMgr, __PHYSICAL_DEVICE* lpBridge, DWORD dwBusNum)
{
	DWORD dwLoop = 0;
	__PHYSICAL_DEVICE* lpPhyDev = NULL;
	DWORD dwSubNum = dwBusNum;

	/* Basic checking. */
	BUG_ON(NULL == lpDevMgr);
	/* 
	 * This routine can be called only in process of system 
	 * initialization,so no locks are obtained when initialize
	 * the physial device list or other global data structures.
	 */
	BUG_ON(!IN_SYSINITIALIZATION());
	if(255 <= dwBusNum)
	{
		/* Maximal bus number should not exceed 255. */
		return MAX_DWORD_VALUE;
	}

	for(dwLoop = 0;dwLoop < MAX_BUS_NUM;dwLoop ++)
	{
		if (BUS_TYPE_NULL == lpDevMgr->SystemBus[dwLoop].dwBusType)
		{
			break;
		}
	}
	if(MAX_BUS_NUM == dwLoop)
	{
		/* Can not find a free bus,the number of system buses exceed MAX_BUS_NUM. */
		return MAX_DWORD_VALUE;
	}

	/* Now we have found a free system bus element,initialize it. */
	lpDevMgr->SystemBus[dwLoop].dwBusType = BUS_TYPE_PCI;
	lpDevMgr->SystemBus[dwLoop].dwBusNum = dwBusNum;
	lpDevMgr->SystemBus[dwLoop].lpHomeBridge = lpBridge;
	if(lpBridge)
	{
		/* If the current bus is not root bus. */
		lpDevMgr->SystemBus[dwLoop].lpParentBus = lpBridge->lpHomeBus;
		lpBridge->lpChildBus = &lpDevMgr->SystemBus[dwLoop];
	}
	//Set PCI bus operations.
	lpDevMgr->SystemBus[dwLoop].ReadConfig  = PciReadConfig;
	lpDevMgr->SystemBus[dwLoop].WriteConfig = PciWriteConfig;

	/* Scan all devices on this bus. */
	PciScanDevices(&lpDevMgr->SystemBus[dwLoop]);
	lpPhyDev = lpDevMgr->SystemBus[dwLoop].lpDevListHdr;
	/* Scan all child buses of the current bus. */
	while(lpPhyDev)
	{
		if(PCI_DEVICE_TYPE_BRIDGE == 
			((__PCI_DEVICE_INFO*)lpPhyDev->lpPrivateInfo)->dwDeviceType)
		{
			/* PCI bridge. */
			dwSubNum = PciScanBus(lpDevMgr,
				lpPhyDev,
				((__PCI_DEVICE_INFO*)lpPhyDev->lpPrivateInfo)->ucSecondary);
		}
		lpPhyDev = lpPhyDev->lpNext;
	}
	return dwSubNum;
}
Ejemplo n.º 8
0
/*
 * Add one PCI device(physical device) into a PCI
 * bus.
 * It first create a physical device and a PCI information structure,then initializes
 * them by reading data from configure space.
 */
static VOID PciAddDevice(DWORD dwConfigReg,__SYSTEM_BUS* lpSysBus)
{
	__PCI_DEVICE_INFO* lpDevInfo = NULL;
	__PHYSICAL_DEVICE* lpPhyDev = NULL;
	BOOL bResult = FALSE;
	DWORD dwTmp = 0;

	/* Basic checking. */
	if ((0 == dwConfigReg) || (NULL == lpSysBus))
	{
		return;
	}
	/* Only available in process of system initialization. */
	BUG_ON(!IN_SYSINITIALIZATION());

	/* Create physical device. */
	lpPhyDev = (__PHYSICAL_DEVICE*)KMemAlloc(sizeof(__PHYSICAL_DEVICE), KMEM_SIZE_TYPE_ANY);
	if (NULL == lpPhyDev)
	{
		goto __TERMINAL;
	}
	memset(lpPhyDev, 0, sizeof(__PHYSICAL_DEVICE));

	/* Create PCI device information structure. */
	lpDevInfo = (__PCI_DEVICE_INFO*)KMemAlloc(sizeof(__PCI_DEVICE_INFO), KMEM_SIZE_TYPE_ANY);
	if (NULL == lpDevInfo)
	{
		goto __TERMINAL;
	}
	memset(lpDevInfo, 0, sizeof(__PCI_DEVICE_INFO));
	
	lpDevInfo->DeviceNum   = (dwConfigReg >> 11) & 0x0000001F;  //Get device number.
	lpDevInfo->FunctionNum = (dwConfigReg >> 8) & 0x00000007;   //Get function number.
	lpPhyDev->lpPrivateInfo = (LPVOID)lpDevInfo;  //Link device information to physical device.

	//Save device number to physical device object.
	lpPhyDev->dwNumber = dwConfigReg & 0x0000FF00;
	lpPhyDev->dwNumber >>= 8;

	/* Initializes identifier member of physical device. */
	dwConfigReg &= 0xFFFFFF00;    //Clear offset part.
	dwConfigReg += PCI_CONFIG_OFFSET_VENDOR;
	__outd(CONFIG_REGISTER,dwConfigReg);
	dwTmp = __ind(DATA_REGISTER);  //Read vendor ID and device ID.

	lpPhyDev->DevId.dwBusType = BUS_TYPE_PCI;
	lpPhyDev->DevId.Bus_ID.PCI_Identifier.ucMask = PCI_IDENTIFIER_MASK_ALL;
	lpPhyDev->DevId.Bus_ID.PCI_Identifier.wVendor = (WORD)dwTmp;
	lpPhyDev->DevId.Bus_ID.PCI_Identifier.wDevice = (WORD)(dwTmp >> 16);

	dwConfigReg &= 0xFFFFFF00;
	dwConfigReg += PCI_CONFIG_OFFSET_REVISION;  //Get revision ID and class code.
	__outd(CONFIG_REGISTER,dwConfigReg);
	dwTmp = __ind(DATA_REGISTER);

	lpPhyDev->DevId.Bus_ID.PCI_Identifier.dwClass = dwTmp;
	/* Save to information struct also. */
	lpDevInfo->dwClassCode = dwTmp;

	dwConfigReg &= 0xFFFFFF00;
	/* Get header type. */
	dwConfigReg += PCI_CONFIG_OFFSET_CACHELINESZ;
	__outd(CONFIG_REGISTER,dwConfigReg);
	dwTmp = __ind(DATA_REGISTER);
	
	/* Get header type. */
	lpPhyDev->DevId.Bus_ID.PCI_Identifier.ucHdrType = (UCHAR)(dwTmp >> 16);

	/* Initializes the resource information required by device. */
	switch((dwTmp >> 16) & 0x7F)
	{
	case 0:         
		/* Normal PCI device. */
		lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_NORMAL;
		dwConfigReg &= 0xFFFFFF00;
		PciFillDevResources(dwConfigReg,lpPhyDev);
		bResult = TRUE;
		break;
	case 1:
		/* PCI-PCI bridge. */
		lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_BRIDGE;
		dwConfigReg &= 0xFFFFFF00;
		PciFillBridgeResources(dwConfigReg,lpPhyDev);
		bResult = TRUE;
		break;
	case 2:
		/* CardBus-PCI bridge. */
		lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_CARDBUS;
		bResult = TRUE;
		break;
	default:
		/* Not supported yet. */
		lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_UNSUPPORTED;
		bResult = TRUE;
		break;
	}

	//Set up physical device's configuration reading/writting routine.
	lpPhyDev->ReadDeviceConfig  = PciReadDeviceConfig;
	lpPhyDev->WriteDeviceConfig = PciWriteDeviceConfig;

	/*
	 * Now,we have finished to initialize resource information,just insert the physical device
	 * object into system bus.
	 */
	lpPhyDev->lpHomeBus = lpSysBus;
	bResult = DeviceManager.AppendDevice(&DeviceManager, lpPhyDev);

__TERMINAL:
	if(!bResult)
	{
		if (lpPhyDev)
		{
			KMemFree((LPVOID)lpPhyDev, KMEM_SIZE_TYPE_ANY, 0);
		}
		if (lpDevInfo)
		{
			KMemFree((LPVOID)lpDevInfo, KMEM_SIZE_TYPE_ANY, 0);
		}
	}
	return;
}
Ejemplo n.º 9
0
static VOID DispatchInterrupt(__COMMON_OBJECT* lpThis,
							  LPVOID           lpEsp,
							  UCHAR ucVector)
{
	__INTERRUPT_OBJECT*    lpIntObject  = NULL;
	__SYSTEM*              lpSystem = (__SYSTEM*)lpThis;
	CHAR                   strError[64];    //To print out the BUG information.

	if((NULL == lpThis) || (NULL == lpEsp))
	{
		return;
	}

	lpSystem->ucIntNestLevel += 1;    //Increment nesting level.
	if(lpSystem->ucIntNestLevel <= 1)
	{
		//Call thread hook here,because current kernel thread is
		//interrupted.
		//If interrupt occurs before any kernel thread is scheduled,
		//lpCurrentKernelThread is NULL.
		if(KernelThreadManager.lpCurrentKernelThread)
		{
			KernelThreadManager.CallThreadHook(
				THREAD_HOOK_TYPE_ENDSCHEDULE,
				KernelThreadManager.lpCurrentKernelThread,
				NULL);
		}
	}
	//For debugging.
	else
	{
#ifdef __CFG_SYS_INTNEST  //Interupt nest is enabled.
		//Do nothing.
#else
		_hx_printf("Fatal error,interrupt nested(enter-int,vector = %d,nestlevel = %d)\r\n",
			ucVector,
			lpSystem->ucIntNestLevel);
		BUG();
#endif
	}

	lpIntObject = lpSystem->lpInterruptVector[ucVector];
	if(NULL == lpIntObject)  //The current interrupt vector has not handler object.
	{
		DefaultIntHandler(lpEsp,ucVector);
		goto __RETFROMINT;
	}

	while(lpIntObject)    //Travel the whole interrupt list of this vector.
	{
		if(lpIntObject->InterruptHandler(lpEsp,
			lpIntObject->lpHandlerParam))    //If an interrupt object handles the interrupt,then returns.
		{
			break;
		}
		lpIntObject = lpIntObject->lpNextInterruptObject;
	}

__RETFROMINT:
	lpSystem->ucIntNestLevel -= 1;    //Decrement interrupt nesting level.
	if(0 == lpSystem->ucIntNestLevel)  //The outmost interrupt.
	{
		if (IN_SYSINITIALIZATION())  //It's a abnormal case.
		{
			_hx_sprintf(strError, "Warning: Interrupt[%d] raised in sys initialization.", ucVector);
			PrintLine(strError);
		}
		else
		{
			KernelThreadManager.ScheduleFromInt((__COMMON_OBJECT*)&KernelThreadManager,
				lpEsp);  //Re-schedule kernel thread.
		}
	}
	else
	{
#ifdef __CFG_SYS_INTNEST  //Interrupt nest is enabled.
		//Do nothing.
#else
		_hx_printf("Fatal error,interrupt nested(leave-int,vector = %d,nestlevel = %d)\r\n",
			ucVector,
			lpSystem->ucIntNestLevel);
		BUG();
#endif  //__CFG_SYS_INTNEST
	}
	return;
}