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; }
//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; }
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; }
/* * 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; }
/* 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); }
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; }
/* * 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; }
/* * 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; }
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; }