📄 syslib.c
字号:
taskSpawn("tDevConn", 11, 0, 10000, vxbDevConnect, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);#endif /* INCLUDE_VXBUS */ }#ifdef LOCAL_MEM_AUTOSIZE/********************************************************************************* WRITE_MEMORY_TEST_PATTERN** This routine writes the memory test pattern used in the sysPhysMemTop()* memory auto-size algorithm. 12 bytes of data stored at <pTestAddr> are* written to <pSaveAddr> before a 12-byte test pattern is written to* <pTestAddr>.** RETURNS: N/A** SEE ALSO: RESTORE_MEMORY_TEST_ADDRS()*/__inline__ static void WRITE_MEMORY_TEST_PATTERN ( int * pTestAddr, int * pSaveAddr ) { pSaveAddr[0] = pTestAddr[0]; pSaveAddr[1] = pTestAddr[1]; pSaveAddr[2] = pTestAddr[2]; pTestAddr[0] = TEST_PATTERN_A; pTestAddr[1] = TEST_PATTERN_B; pTestAddr[2] = TEST_PATTERN_C; cacheFlush (DATA_CACHE, pTestAddr, 16); }/********************************************************************************* RESTORE_MEMORY_TEST_ADDRS** This routine restores memory test locations which are modified in the* sysPhysMemTop() memory auto-size algorithm. 12 bytes of data stored at* <pSaveAddr> are written to <pTestAddr>.** RETURNS: N/a** SEE ALSO: WRITE_MEMORY_TEST_PATTERN()*/__inline__ static void RESTORE_MEMORY_TEST_ADDRS ( int * pTestAddr, const int * pSaveAddr ) { pTestAddr[0] = pSaveAddr[0]; pTestAddr[1] = pSaveAddr[1]; pTestAddr[2] = pSaveAddr[2]; }#endif /* LOCAL_MEM_AUTOSIZE *//********************************************************************************* sysPhysMemTop - get the address of the top of physical memory** This routine returns the address of the first missing byte of memory,* which indicates the top of physical memory.** INTERNAL* The memory auto-size logic assumes that the manifest constant PHYS_MEM_MAX* specifies the total size in bytes of the processor's physical address space.* In the case of IA-32 processors, PHYS_MEM_MAX will be 4GB (2^32 bytes) or* 64GB (2^36 bytes) if the 36-bit Physical Address Extension (PAE) is enabled* on select processor models. However, because the tool-chain and sysMemTop()* API are 32-bit, this routine currently will not auto-size a 36-bit address* space. Moreover, this routine will not return the memory top of a platform* with a memory device using a full 2^32 bytes of address space, as the memory* top of such a device would be a 33-bit value.** When paging is used, the processor divides the linear address space into* fixed-size pages (of 4KB, 2MB, or 4MB in length) that can be mapped into* physical memory and/or disk storage. The auto-size algorithm organizes* the physical address space using the same concept. That is, rather than* treating the address space as an array of bytes, the memory auto-size* code treats the address space as an array of equal-sized pages.** The auto-size algorithm attempts to locate the base-address of the first* non-existent page address in the physical address space. This is done by* writing, and then reading, a test pattern to each page base-address in the* address space. If the test pattern is not read back from a page, it is* assumed that the address does not physically exist.** As the installed physical memory could be potentially quite large, the* auto-size code attempts a few optimizations, chief among these being a* binary (as opposed to linear) search of the page array (ie. address space).* An additional optimization is obtained by avoiding a search on memory* that _must_ exist; namely, the memory storing the VxWorks boot image or* RTOS image from whence this routine will execute.** In the case of VxWorks boot and RTOS images for IA-32, the last byte of the* image section loaded highest in memory is assumed to be indicated by the* address of a symbol, named <end>, which is typically supplied by the linker* (more precisely, the linker script) used to build the image. The search* for remaining extant physical page addresses on the system will use the* address of the first page following the <end> symbol, or a page-aligned* address no lower than physical memory location 0x100000 (1Mb), as a lower* bound on the search. All memory locations below physical address 0x100000* are assumed to be reserved existing target memory.** RETURNS: The address of the top of physical memory.*/char * sysPhysMemTop (void) { PHYS_MEM_DESC * pMmu; /* points to memory desc. table entries */ UINT32 tempMTP; /* temporary variable to stop warnings */ GDTPTR gDtp; INT32 nGdtEntries, nGdtBytes; BOOL found = FALSE; if (memTopPhys != NULL) { return (memTopPhys); }#ifdef LOCAL_MEM_AUTOSIZE { /* Do not use a page-sized stride larger than 4Kb, as the end of usable * memory could possibly be within a 2Mb or 4Mb page memory range. */ const UINT32 pageSize = PAGE_SIZE_4KB; /* The lower bound for the probe will be the page-aligned VxWorks * end-of-image address, or a page-aligned address no less than * the 1Mb physical address. */ UINT8 * pPage = (UINT8 *) ROUND_UP (((UINT32)(&end) > 0x100000) ? (UINT32)(&end) : (0x100000), pageSize); /* Subtract the number of used pages from the total number of pages * possible in the address space. The resulting value is the total * number of pages that could possibly populate the remaining address * space above <pPage>. */ const UINT32 pageNoUsed = ((UINT32) pPage / pageSize); const UINT32 pageNoTotal = (PHYS_MEM_MAX / pageSize) - pageNoUsed; UINT32 delta = HALF (pageNoTotal); int temp[4]; /* find out the actual size of the memory (up to PHYS_MEM_MAX) */ for (pPage += (pageSize * delta); delta != 0; delta >>= 1) { WRITE_MEMORY_TEST_PATTERN ((int *) pPage, &temp[0]); if (*((int *) pPage) != TEST_PATTERN_A) { /* The test pattern was not written, so assume that <pPage> is the * base address of a page beyond available memory. Test the * next lowest page. If the test pattern is writable there, assume * that <pPage> is the address of the first byte beyond the last * addressable page. */ UINT8 * pPrevPage = (UINT8 *)((UINT32) pPage - pageSize); WRITE_MEMORY_TEST_PATTERN ((int *) pPrevPage, &temp[0]); if (*((int *) pPrevPage) == TEST_PATTERN_A) { RESTORE_MEMORY_TEST_ADDRS ((int *) pPrevPage, &temp[0]); memTopPhys = (char *)pPage; found = TRUE; break; } pPage -= (pageSize * HALF (delta)); } else { /* The test pattern was written, so assume that <pPage> is the base * address of a page in available memory. Test the next highest * page. If the test pattern is not writable there, assume that * <pNextPage> is the address of the first byte beyond that last * addressable page. */ UINT8 * pNextPage = (UINT8 *)((UINT32) pPage + pageSize); RESTORE_MEMORY_TEST_ADDRS ((int *) pPage, &temp[0]); WRITE_MEMORY_TEST_PATTERN ((int *) pNextPage, &temp[0]); if (*((int *) pNextPage) != TEST_PATTERN_A) { memTopPhys = (char *)pNextPage; found = TRUE; break; } RESTORE_MEMORY_TEST_ADDRS ((int *) pNextPage, &temp[0]); pPage += (pageSize * HALF (delta)); } } }#endif /* LOCAL_MEM_AUTOSIZE */ if (!found) { memTopPhys = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE); } /* copy the global descriptor table from RAM/ROM to RAM */ /* Get the Global Data Table Descriptor */ vxGdtrGet ( (long long int *)&gDtp ); /* Extract the number of bytes */ nGdtBytes = (INT32)gDtp.wGdtr[0]; /* and calculate the number of entries */ nGdtEntries = (nGdtBytes + 1 ) / sizeof(GDT); bcopy ((char *)sysGdt, (char *)pSysGdt, nGdtEntries * sizeof(GDT)); /* * We assume that there are no memory mapped IO addresses * above the "memTopPhys" if INCLUDE_PCI is not defined. * Thus we set the "limit" to get the General Protection Fault * when the memory above the "memTopPhys" is accessed. */#if !defined (INCLUDE_PCI) && \ !defined (INCLUDE_MMU_BASIC) && !defined (INCLUDE_MMU_FULL) { int ix; GDT * pGdt = pSysGdt; int limit = (((UINT32) memTopPhys) >> 12) - 1; for (ix = 1; ix < GDT_ENTRIES; ++ix) { ++pGdt; pGdt->limit00 = limit & 0x0ffff; pGdt->limit01 = ((limit & 0xf0000) >> 16) | (pGdt->limit01 & 0xf0); } }#endif /* INCLUDE_PCI */ /* load the global descriptor table. set the MMU table */ sysLoadGdt ((char *)&gDtp);#ifdef FAST_REBOOT /* * save the brand new bootrom image that will be protected by MMU. * The last 2 bytes of ROM_SIZE are for the checksum. * - compression would minimize the DRAM usage. * - when restore, jumping to the saved image would be faster. */ memTopPhys -= ROM_SIZE; bcopy ((char *)ROM_BASE_ADRS, memTopPhys, ROM_SIZE); *(UINT16 *)(memTopPhys + ROM_SIZE - 2) = checksum ((UINT16 *)memTopPhys, ROM_SIZE - 2); memRom = memTopPhys; /* remember it */#endif /* FAST_REBOOT */ /* set the MMU descriptor table */#if 0 (UINT32)memTopPhys &= ~(VM_PAGE_SIZE - 1); /* VM_PAGE_SIZE aligned */#endif tempMTP = (UINT32)memTopPhys & ~(VM_PAGE_SIZE - 1); /* VM_PAGE_SIZE aligned */ memTopPhys = (char *)tempMTP;#if (VM_PAGE_SIZE == PAGE_SIZE_4KB) pMmu = &sysPhysMemDesc[4]; /* 5th entry: above 1.5MB upper memory */ pMmu->len = (UINT32) memTopPhys - (UINT32) pMmu->physicalAddr;#else /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */ pMmu = &sysPhysMemDesc[2]; /* 3rd entry: above 8MB upper memory */ pMmu->len = (UINT32) memTopPhys - (UINT32) pMmu->physicalAddr;#endif /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */ return (memTopPhys); }/********************************************************************************* sysMemTop - get the address of the top of VxWorks memory** This routine returns a pointer to the first byte of memory not* controlled or used by VxWorks.** The user can reserve memory space by defining the macro USER_RESERVED_MEM* in config.h. This routine returns the address of the reserved memory* area. The value of USER_RESERVED_MEM is in bytes.** RETURNS: The address of the top of VxWorks memory.*/char * sysMemTop (void) { static char * memTop = NULL; if (memTop == NULL) { memTop = sysPhysMemTop () - USER_RESERVED_MEM;#ifdef INCLUDE_EDR_PM /* account for ED&R persistent memory */ memTop = memTop - PM_RESERVED_MEM;#endif if ((UINT32)(&end) < 0x100000) /* this is for bootrom */ memTop = (char *)EBDA_START; /* preserve the MP table */ else if ((UINT32)(&end) < RAM_LOW_ADRS) /* bootrom in upper mem */ memTop = (char *)(RAM_LOW_ADRS & 0xfff00000); } return (memTop); }/********************************************************************************* sysToMonitor - transfer control to the ROM monitor** This routine transfers control to the ROM monitor. It is usually called* only by reboot() -- which services ^X -- and by bus errors at interrupt* level. However, in some circumstances, the user may wish to introduce a* new <startType> to enable special boot ROM facilities.** RETURNS: Does not return.*/STATUS sysToMonitor ( int startType /* passed to ROM to tell it how to boot */ ) { FUNCPTR pEntry; INT16 * pDst; VM_ENABLE (FALSE); /* disable MMU */#if (CPU == PENTIUM) || (CPU == PENTIUM2) || (CPU == PENTIUM3) || \ (CPU == PE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -