DEMOD_STATUS cnxt_lnb_set_tone_enable( NIM *pNIM, bool enable ) { #if RTOS != NOOS int api_error; #endif /* RTOS != NOOS */ #if (LNB_22KHZ_CONTROL == LNB_22KHZ_ENABLE) LNBMODE lnbmode; #else LNBTONE tone; #endif #if (LNB_22KHZ_CONTROL == LNB_22KHZ_ENABLE) if ( enable == FALSE ) { lnbmode.lnb_mode = LNBMODE_MANUAL_ZERO; } else { lnbmode.lnb_mode = LNBMODE_MANUAL_ONE; } if ( !API_SetLNBMode( pNIM, &lnbmode ) ) { #if RTOS != NOOS trace_new( TL_ERROR, "API_SetLNBMode failed. " "File: %s, line: %d\n", API_GetErrorFilename( pNIM ), API_GetErrorLineNumber( pNIM ) ); api_error = API_GetLastError( pNIM ); trace_new( TL_ERROR, "Error %d, %s\n", api_error, API_GetErrorMessage( pNIM, (APIERRNO)api_error) ); #endif /* RTOS != NOOS */ return DEMOD_ERROR; } #else if ( enable ) { tone = LNBTONE_ON; } else { tone = LNBTONE_OFF; } if ( !API_SetLNBTone( pNIM, tone ) ) { #if RTOS != NOOS trace_new( TL_ERROR, "API_SetLNBTone failed. File: %s, line: %d\n", API_GetErrorFilename( pNIM ), API_GetErrorLineNumber( pNIM ) ); api_error = API_GetLastError( pNIM ); trace_new( TL_ERROR, "Error %d, %s\n", api_error, API_GetErrorMessage( pNIM, (APIERRNO)api_error) ); #endif /* RTOS != NOOS */ return DEMOD_ERROR; } #endif lnb_state.tone_enabled = enable; return DEMOD_SUCCESS; }
/********************************************************************************************************* ** 函数名称: API_TimeSleepUntil ** 功能描述: 线程睡眠直到一个指定的时间 (与当前时钟差值不得超过 ULONG_MAX 个 tick) ** 输 入 : clockid 时钟类型 CLOCK_REALTIME or CLOCK_MONOTONIC ** tv 指定的时间 ** bSigRet 是否允许信号唤醒 ** 输 出 : ERROR_NONE or EINTR ** 全局变量: ** 调用模块: API 函数 (不得在中断中调用) *********************************************************************************************************/ LW_API ULONG API_TimeSleepUntil (clockid_t clockid, const struct timespec *tv, BOOL bSigRet) { struct timespec tvNow; struct timespec tvTemp; if ((clockid != CLOCK_REALTIME) && (clockid != CLOCK_REALTIME)) { _ErrorHandle(EINVAL); return (EINVAL); } lib_clock_gettime(clockid, &tvNow); if (!__timespecLeftTime(&tvNow, tv)) { return (ERROR_NONE); } tvTemp = *tv; __timespecSub(&tvTemp, &tvNow); if (nanosleep(&tvTemp, LW_NULL)) { return (API_GetLastError()); } else { return (ERROR_NONE); } }
DEMOD_STATUS cnxt_lnb_set_polarization( NIM *pNIM, NIM_SATELLITE_POLARISATION polarization ) { #if RTOS != NOOS int api_error; #endif /* RTOS != NOOS */ LNBPOL polarization_voltage; lnb_state.polarization = polarization; /* Polarization voltage is calculated the same way for all LNB types. */ switch ( polarization ) { case M_HORIZONTAL: polarization_voltage = (LNBPOL)( lnb_parameters.horizontal_voltage == V_12VOLTS ? LNB_LOW : LNB_HIGH ); break; case M_LEFT: polarization_voltage = (LNBPOL)( lnb_parameters.left_voltage == V_12VOLTS ? LNB_LOW : LNB_HIGH ); break; case M_VERTICAL: polarization_voltage = (LNBPOL)( lnb_parameters.vertical_voltage == V_12VOLTS ? LNB_LOW : LNB_HIGH ); break; case M_RIGHT: polarization_voltage = (LNBPOL)( lnb_parameters.right_voltage == V_12VOLTS ? LNB_LOW : LNB_HIGH ); break; default: #if RTOS != NOOS error_log( ERROR_WARNING | RC_SDM_BADVAL ); #endif /* RTOS != NOOS */ polarization_voltage = (LNBPOL)( lnb_parameters.right_voltage == V_12VOLTS ? LNB_LOW : LNB_HIGH ); lnb_state.polarization = M_RIGHT; } if ( !API_SetLNBDC( pNIM, polarization_voltage ) ) { #if RTOS != NOOS trace_new( TL_ERROR, "API_SetLNBDC failed. File: %s, line: %d\n", API_GetErrorFilename( pNIM ), API_GetErrorLineNumber( pNIM ) ); api_error = API_GetLastError( pNIM ); trace_new( TL_ERROR, "Error %d, %s\n", api_error, API_GetErrorMessage( pNIM, (APIERRNO)api_error) ); #endif /* RTOS != NOOS */ return DEMOD_ERROR; } return DEMOD_SUCCESS; }
DEMOD_STATUS cnxt_lnb_set_output_enable( NIM *pNIM, bool enable ) { #if (INTERNAL_DEMOD == INTERNAL_COBRA_LIKE) #else #if RTOS != NOOS int api_error; #endif /* RTOS != NOOS */ #endif /* Set up the LNB enable signal. It is different for internal/external. */ #if (INTERNAL_DEMOD == INTERNAL_COBRA_LIKE) /* LNB enable signal is driven from the PIO expander; set to 1 to enable, 0 to disable. */ cnxt_gpio_set_output_level( PIO_LNB_ENABLE, enable ); lnb_state.enabled = enable; #else /* Cobra GPIO4 is the enable for the external LNB signal generator; set to 1 to enable, 0 to disable. */ if ( RegisterWrite( pNIM, CX24130_GPIO4VAL, enable ) == True ) { lnb_state.enabled = enable; } else { #if RTOS != NOOS trace_new( TL_ERROR, "Cobra demod failed to write to LNB signal enable" " (GPIO4).\n" ); trace_new( TL_ERROR, "File: %s, line: %d\n", API_GetErrorFilename(pNIM), API_GetErrorLineNumber(pNIM) ); api_error = API_GetLastError( pNIM ); trace_new( TL_ERROR, "Error %d, %s\n", api_error, API_GetErrorMessage(pNIM, (APIERRNO)api_error) ); #endif /* RTOS != NOOS */ return DEMOD_ERROR; } #endif return DEMOD_SUCCESS; }
/********************************************************************************************************* ** 函数名称: API_OemDiskMountEx2 ** 功能描述: 自动挂载一个磁盘的所有分区. 可以使用指定的文件系统类型挂载 ** 输 入 : pcVolName 根节点名字 (当前 API 将根据分区情况在末尾加入数字) ** pblkdDisk 物理磁盘控制块 (必须是直接操作物理磁盘) ** pvDiskCacheMem 磁盘 CACHE 缓冲区的内存起始地址 (为零表示动态分配磁盘缓冲) ** stMemSize 磁盘 CACHE 缓冲区大小 (为零表示不需要 DISK CACHE) ** iMaxRBurstSector 磁盘猝发读的最大扇区数 ** iMaxWBurstSector 磁盘猝发写的最大扇区数 ** pcFsName 文件系统类型, 例如: "vfat" "tpsfs" "iso9660" "ntfs" ... ** bForceFsType 是否强制使用指定的文件系统类型 ** 输 出 : OEM 磁盘控制块 ** 全局变量: ** 调用模块: ** 注 意 : 挂载的文件系统不包含 yaffs 文件系统, yaffs 属于静态文件系统. API 函数 *********************************************************************************************************/ LW_API PLW_OEMDISK_CB API_OemDiskMountEx2 (CPCHAR pcVolName, PLW_BLK_DEV pblkdDisk, PVOID pvDiskCacheMem, size_t stMemSize, INT iMaxRBurstSector, INT iMaxWBurstSector, CPCHAR pcFsName, BOOL bForceFsType) { INT i; INT iErrLevel = 0; REGISTER ULONG ulError; CHAR cFullVolName[MAX_FILENAME_LENGTH]; /* 完整卷标名 */ INT iBlkIo; INT iBlkIoErr; PCHAR pcTail; INT iVolSeq; REGISTER INT iNPart; DISKPART_TABLE dptPart; /* 分区表 */ PLW_OEMDISK_CB poemd; FUNCPTR pfuncFsCreate; /* * 挂载节点名检查 */ if (pcVolName == LW_NULL || *pcVolName != PX_ROOT) { /* 名字错误 */ _ErrorHandle(EINVAL); return (LW_NULL); } i = (INT)lib_strnlen(pcVolName, (PATH_MAX - __OEM_DISK_TAIL_LEN)); if (i >= (PATH_MAX - __OEM_DISK_TAIL_LEN)) { /* 名字过长 */ _ErrorHandle(ERROR_IO_NAME_TOO_LONG); return (LW_NULL); } /* * 分配 OEM 磁盘控制块内存 */ poemd = (PLW_OEMDISK_CB)__SHEAP_ALLOC(sizeof(LW_OEMDISK_CB) + (size_t)i); if (poemd == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n"); _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (LW_NULL); } lib_bzero(poemd, sizeof(LW_OEMDISK_CB) + i); /* 清空 */ poemd->OEMDISK_pblkdDisk = pblkdDisk; /* * 分配磁盘缓冲内存 */ if ((pvDiskCacheMem == LW_NULL) && (stMemSize > 0)) { /* 是否需要动态分配磁盘缓冲 */ poemd->OEMDISK_pvCache = __SHEAP_ALLOC(stMemSize); if (poemd->OEMDISK_pvCache == LW_NULL) { _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); /* 系统缺少内存 */ goto __error_handle; } pvDiskCacheMem = poemd->OEMDISK_pvCache; } /* * 创建物理磁盘缓冲, 同时会初始化磁盘 */ if (stMemSize) { ulError = API_DiskCacheCreateEx(pblkdDisk, pvDiskCacheMem, stMemSize, iMaxRBurstSector, iMaxWBurstSector, &poemd->OEMDISK_pblkdCache); if (ulError) { iErrLevel = 1; goto __error_handle; } } else { poemd->OEMDISK_pblkdCache = pblkdDisk; /* 不需要磁盘缓冲 */ } /* * 创建 blk io 设备 */ pcTail = lib_rindex(pcVolName, PX_DIVIDER); if (pcTail == LW_NULL) { pcTail = (PCHAR)pcVolName; } else { pcTail++; } for (iBlkIo = 0; iBlkIo < 64; iBlkIo++) { snprintf(cFullVolName, MAX_FILENAME_LENGTH, "%s%s%d", LW_BLKIO_PERFIX, pcTail, iBlkIo); if (API_IosDevMatchFull(cFullVolName) == LW_NULL) { iBlkIoErr = API_OemBlkIoCreate(cFullVolName, poemd->OEMDISK_pblkdCache); if (iBlkIoErr == ERROR_NONE) { break; } else if (errno != ERROR_IOS_DUPLICATE_DEVICE_NAME) { iErrLevel = 2; goto __error_handle; } } } /* * 扫面磁盘所有分区信息 */ iNPart = API_DiskPartitionScan(poemd->OEMDISK_pblkdCache, &dptPart); /* 扫描分区表 */ if (iNPart < 1) { iErrLevel = 3; goto __error_handle; } poemd->OEMDISK_uiNPart = (UINT)iNPart; /* 记录分区数量 */ /* * 初始化所有的分区挂载失败 */ for (i = 0; i < iNPart; i++) { poemd->OEMDISK_iVolSeq[i] = PX_ERROR; /* 默认为挂载失败 */ } /* * 分别挂载各个分区 */ iVolSeq = 0; for (i = 0; i < iNPart; i++) { /* 装载各个分区 */ if (API_DiskPartitionGet(&dptPart, i, &poemd->OEMDISK_pblkdPart[i]) < 0) { /* 获得分区 logic device */ break; } __refined_seq: sprintf(cFullVolName, "%s%d", pcVolName, iVolSeq); /* 获得完整卷名 */ if (API_IosDevMatchFull(cFullVolName)) { /* 设备名重名预判 */ iVolSeq++; goto __refined_seq; /* 重新确定卷序号 */ } pfuncFsCreate = LW_NULL; switch (dptPart.DPT_dpoLogic[i].DPO_dpnEntry.DPN_ucPartType) { /* 判断文件系统分区类型 */ case LW_DISK_PART_TYPE_FAT12: /* FAT 文件系统类型 */ case LW_DISK_PART_TYPE_FAT16: case LW_DISK_PART_TYPE_FAT16_BIG: case LW_DISK_PART_TYPE_WIN95_FAT32: case LW_DISK_PART_TYPE_WIN95_FAT32LBA: case LW_DISK_PART_TYPE_WIN95_FAT16LBA: if (bForceFsType) { /* 是否强制指定文件系统类型 */ pfuncFsCreate = __fsCreateFuncGet(pcFsName); } else { pfuncFsCreate = __fsCreateFuncGet("vfat"); } break; case LW_DISK_PART_TYPE_TPS: if (bForceFsType) { /* 是否强制指定文件系统类型 */ pfuncFsCreate = __fsCreateFuncGet(pcFsName); } else { pfuncFsCreate = __fsCreateFuncGet("tpsfs"); } break; default: /* 默认使用指定文件系统类型 */ if (bForceFsType) { /* 是否强制指定文件系统类型 */ pfuncFsCreate = __fsCreateFuncGet(pcFsName); } break; } if (pfuncFsCreate) { /* 存在支持的文件系统 */ if (pfuncFsCreate(cFullVolName, poemd->OEMDISK_pblkdPart[i]) < 0) { /* 挂载文件系统 */ if (API_GetLastError() == ERROR_IOS_DUPLICATE_DEVICE_NAME) { iVolSeq++; goto __refined_seq; /* 重新确定卷序号 */ } else { goto __mount_over; /* 挂载失败 */ } } poemd->OEMDISK_pdevhdr[i] = API_IosDevMatchFull(cFullVolName); poemd->OEMDISK_iVolSeq[i] = iVolSeq; /* 记录卷序号 */ } else { continue; /* 此分区无法加载 */ } if (poemd->OEMDISK_iVolSeq[i] >= 0) { __oemDiskForceDeleteEn(cFullVolName); /* 默认为强制删除 */ } iVolSeq++; /* 已处理完当前卷 */ } __mount_over: /* 所有分区挂载完毕 */ lib_strcpy(poemd->OEMDISK_cVolName, pcVolName); /* 拷贝名字 */ return (poemd); __error_handle: if (iErrLevel > 2) { if (poemd->OEMDISK_pblkdCache) { API_OemBlkIoDelete(poemd->OEMDISK_pblkdCache); } } if (iErrLevel > 1) { if (poemd->OEMDISK_pblkdCache != pblkdDisk) { API_DiskCacheDelete(poemd->OEMDISK_pblkdCache); } } if (iErrLevel > 0) { if (poemd->OEMDISK_pvCache) { __SHEAP_FREE(poemd->OEMDISK_pvCache); } } __SHEAP_FREE(poemd); return (LW_NULL); }
/********************************************************************************************************* ** 函数名称: waitread ** 功能描述: select() 变种,等待单个文件可读. ** 输 入 : iFd 文件描述符 ** ptmvalTO 等待超时时间, LW_NULL 表示永远等待. ** 输 出 : 正常等待到的文件数, 为 1 表示文件可以读, 为 0 表示超时 ,错误返回 PX_ERROR. ** errno == ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER 驱动程序不支持 ** errno == ERROR_IO_SELECT_CONTEXT 线程不存在 context ** errno == ERROR_THREAD_WAIT_TIMEOUT 等待超时 ** errno == ERROR_KERNEL_IN_ISR 在中断中调用 ** errno == ERROR_IOS_INVALID_FILE_DESCRIPTOR 文件描述符无效. ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API INT waitread (INT iFd, struct timeval *ptmvalTO) { REGISTER INT iIsOk = ERROR_NONE; /* 初始化为没有错误 */ REGISTER INT iWidth = iFd + 1; /* iFd + 1 */ REGISTER INT iWidthInBytes; /* 需要检测的位数占多少字节 */ REGISTER ULONG ulWaitTime; /* 等待时间 */ REGISTER LW_SEL_CONTEXT *pselctx; PLW_CLASS_TCB ptcbCur; fd_set fdsetRead; LW_SEL_WAKEUPNODE selwunNode; /* 生成的 NODE 模板 */ ULONG ulError; if (LW_CPU_GET_CUR_NESTING()) { _ErrorHandle(ERROR_KERNEL_IN_ISR); /* 不能在中断中调用 */ return (PX_ERROR); } if (iFd > (FD_SETSIZE - 1) || iFd < 0) { /* 文件号错误 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "file descriptor invalidate..\r\n"); _ErrorHandle(ERROR_IOS_INVALID_FILE_DESCRIPTOR); /* 文件描述符无效 */ return (PX_ERROR); } LW_TCB_GET_CUR_SAFE(ptcbCur); pselctx = ptcbCur->TCB_pselctxContext; if (!pselctx) { /* 没有 select context */ _DebugHandle(__ERRORMESSAGE_LEVEL, "no select context.\r\n"); _ErrorHandle(ERROR_IO_SELECT_CONTEXT); return (PX_ERROR); } iWidthInBytes = __HOWMANY(iWidth, NFDBITS) * sizeof(fd_mask); /* 需要检测的位数占多少字节 */ FD_ZERO(&fdsetRead); /* 清除文件集 */ FD_SET(iFd, &fdsetRead); /* 指定文件置位 */ __selFdsetInit(iWidthInBytes, &fdsetRead, /* 设置 OrigRead 文件位 */ LW_NULL, LW_NULL, pselctx); /* __selTaskDeleteHook 使用 */ FD_CLR(iFd, &fdsetRead); /* 清除文件集 */ if (!ptmvalTO) { /* 计算等待时间 */ ulWaitTime = LW_OPTION_WAIT_INFINITE; /* 无限等待 */ } else { ulWaitTime = __timevalToTick(ptmvalTO); /* 计算超时时间 */ } pselctx->SELCTX_pfdsetReadFds = &fdsetRead; pselctx->SELCTX_pfdsetWriteFds = LW_NULL; /* 保存用户参数地址 */ pselctx->SELCTX_pfdsetExceptFds = LW_NULL; API_SemaphoreBClear(pselctx->SELCTX_hSembWakeup); /* 清除信号量 */ selwunNode.SELWUN_hThreadId = API_ThreadIdSelf(); selwunNode.SELWUN_seltypType = SELREAD; selwunNode.SELWUN_iFd = iFd; pselctx->SELCTX_iWidth = iWidth; /* 记录最大文件号 */ pselctx->SELCTX_bPendedOnSelect = LW_TRUE; /* 需要 delete hook 清除 NODE */ iIsOk = ioctl(iFd, FIOSELECT, (LONG)&selwunNode); /* FIOSELECT */ if (iIsOk != ERROR_NONE) { ULONG ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ if (ulError == ERROR_IO_UNKNOWN_REQUEST) { _ErrorHandle(ERROR_IO_SELECT_UNSUPPORT_IN_DRIVER); /* 驱动程序不支持 */ } pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ return (PX_ERROR); /* 错误 */ } API_SemaphoreBPend(pselctx->SELCTX_hSembWakeup, ulWaitTime); /* 开始等待 */ ulError = API_GetLastError(); iIsOk = ioctl(iFd, FIOUNSELECT, (LONG)&selwunNode); /* FIOUNSELECT */ pselctx->SELCTX_bPendedOnSelect = LW_FALSE; /* 自行清理完毕 */ if (iIsOk != ERROR_NONE) { return (PX_ERROR); /* 出现错误 */ } else { _ErrorHandle(ulError); } if (FD_ISSET(iFd, &fdsetRead)) { /* 检查文件是否可读 */ return (1); } else { return (0); } }
DEMOD_STATUS cnxt_lnb_init( NIM *pNIM ) { #if (INTERNAL_DEMOD == INTERNAL_COBRA_LIKE) #else #if RTOS != NOOS int api_error; #endif /* RTOS != NOOS */ #endif /* Set the PIO that controls the direction of the 22KHz signal for output as the initial setting. Any DiSEqC input will need to change it. */ #if PIO_LNB_22KHZ_DIRECTION != GPIO_INVALID /* * !!! HACK ALERT !!! * WARNING!!!!! Hack required to keep from setting this PIO on a * Bronco1. When Bronco1 boards disappear, so should this hack. (PIO * setting should become conditional only upon value of * PIO_LNB_22KHZ_DIRECTION != GPIO_INVALID.) * !!! HACK ALERT !!! */ #if I2C_CONFIG_EEPROM_ADDR != NOT_PRESENT { extern int ConfigurationValid; extern CONFIG_TABLE config_table; if ( ConfigurationValid && ( config_table.board_type != 0x00 || ((config_table.board_type == 0x00) && (config_table.board_rev != 0x01)) ) ) { cnxt_gpio_set_output_level( PIO_LNB_22KHZ_DIRECTION, TRUE ); } } #endif /* * !!! HACK ALERT !!! * !!! HACK ALERT !!! */ #endif /* Set up directional control for the PIO controlling LNB enable. */ #if (INTERNAL_DEMOD == INTERNAL_COBRA_LIKE) /* No direction control necessary. */ #else /* Cobra GPIO4 is the enable for the external LNB signal generator; set as an output. */ if ( RegisterWrite( pNIM, CX24130_GPIO4DIR, 1 ) != True ) { #if RTOS != NOOS trace_new( TL_ERROR, "Cobra demod failed to set direction of LNB signal enable" " (GPIO4).\n" ); trace_new( TL_ERROR, "File: %s, line: %d\n", API_GetErrorFilename(pNIM), API_GetErrorLineNumber(pNIM) ); api_error = API_GetLastError( pNIM ); trace_new( TL_ERROR, "Error %d, %s\n", api_error, API_GetErrorMessage(pNIM, (APIERRNO)api_error) ); #endif /* RTOS != NOOS */ return DEMOD_ERROR; } #endif /* Actually enable LNB output unless initialization with output disabled is requested. */ #ifndef LNB_INITIALLY_DISABLED cnxt_lnb_set_output_enable( pNIM, TRUE ); #endif return DEMOD_SUCCESS; }
/********************************************************************************************************* ** 函数名称: API_VmmLibPrimaryInit ** 功能描述: 初始化 vmm 库 (注意: LW_VMM_ZONE_DESC 结构表内的元素数一定要与 LW_CFG_VMM_ZONE_NUM 一致) ** 输 入 : vmzone 物理内存区 ** mmugdesc 全局映射关系描述表 ** pcMachineName 正在运行的机器名称 ** 输 出 : ERROR CODE ** 全局变量: ** 调用模块: ** 注 意 : 多核模式为主核 MMU 初始化 API 函数 *********************************************************************************************************/ LW_API ULONG API_VmmLibPrimaryInit (LW_VMM_ZONE_DESC vmzone[], LW_MMU_GLOBAL_DESC mmugdesc[], CPCHAR pcMachineName) { static BOOL bIsInit = LW_FALSE; PLW_MMU_VIRTUAL_DESC pvirdesc = __vmmVirtualDesc(); INT i; ULONG ulError; ULONG ulPageNum = 0; if (bIsInit) { return (ERROR_NONE); } if ((vmzone == LW_NULL) || (mmugdesc == LW_NULL)) { _ErrorHandle(EINVAL); return (EINVAL); } for (i = 0; i < LW_CFG_VMM_ZONE_NUM; i++) { ulPageNum += (ULONG)(vmzone[i].ZONED_stSize >> LW_CFG_VMM_PAGE_SHIFT); } ulError = __pageCbInit(ulPageNum); /* 初始化物理页面控制块池 */ if (ulError) { _ErrorHandle(ulError); return (ulError); } for (i = 0; i < LW_CFG_VMM_ZONE_NUM; i++) { ulError = __vmmPhysicalCreate((ULONG)i, vmzone[i].ZONED_ulAddr, vmzone[i].ZONED_stSize, vmzone[i].ZONED_uiAttr);/* 初始化物理 zone */ if (ulError) { _ErrorHandle(ulError); return (ulError); } ulError = __areaPhysicalSpaceInit((ULONG)i, vmzone[i].ZONED_ulAddr, vmzone[i].ZONED_stSize); if (ulError) { _ErrorHandle(ulError); return (ulError); } } ulError = __vmmVirtualCreate(pvirdesc->ulVirtualStart, pvirdesc->stSize); /* 初始化逻辑空间 */ if (ulError) { _ErrorHandle(ulError); return (ulError); } ulError = __areaVirtualSpaceInit(pvirdesc->ulVirtualStart, pvirdesc->stSize); if (ulError) { _ErrorHandle(ulError); return (ulError); } _G_ulVmmLock = API_SemaphoreMCreate("vmm_lock", LW_PRIO_DEF_CEILING, LW_OPTION_INHERIT_PRIORITY | LW_OPTION_WAIT_PRIORITY | LW_OPTION_DELETE_SAFE | LW_OPTION_OBJECT_GLOBAL, /* 基于优先级等待 */ LW_NULL); if (!_G_ulVmmLock) { return (API_GetLastError()); } __vmmMapInit(); /* 初始化映射管理库 */ ulError = __vmmLibPrimaryInit(mmugdesc, pcMachineName); /* 初始化底层 MMU */ if (ulError) { _ErrorHandle(ulError); return (ulError); } bIsInit = LW_TRUE; _DebugHandle(__LOGMESSAGE_LEVEL, "MMU initilaized.\r\n"); return (ERROR_NONE); /* 初始化底层 MMU */ }