?? syslib.c
字號:
}
/*******************************************************************************
*
* 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.
*
* Memory probing begins at the end of BSS; at every 4K boundary a byte
* is read until it finds one that cannot be read, or 4MB have been probed,
* whichever is first.
*
* RETURNS: The address of the top of physical memory.
*
* INTERNAL
* This routine is used by sysHwInit() to differentiate between models.
* It is highly questionable whether vxMemProbe() can be used during the
* initial stage of booting.
*/
char *sysPhysMemTop (void)
{
#define TEST_PATTERN 0x12345678
#define SYS_PAGE_SIZE 0x10000
#define N_TIMES 3
static char *memTop = NULL; /* top of memory */
int delta = SYS_PAGE_SIZE;
BOOL found = FALSE;
PHYS_MEM_DESC *pMmu;
int temp[N_TIMES];
char gdtr[6];
char *p;
int ix;
if (memTop != NULL)
return (memTop);
/* if (&end) is in upper memory, we assume it is VxWorks image.
* if not, it is Boot image */
if ((int)&end > 0x100000)
p = (char *)(((int)&end + (delta - 1)) & (~ (delta - 1)));
else
p = (char *)0x100000;
/* find out the actual size of the memory (max 1GB) */
for (; (int)p < 0x40000000; p += delta)
{
for (ix=0; ix<N_TIMES; ix++) /* save and write */
{
temp[ix] = *((int *)p + ix);
*((int *)p + ix) = TEST_PATTERN;
}
cacheFlush (DATA_CACHE, p, 4 * sizeof(int)); /* for 486, Pentium */
if (*(int *)p != TEST_PATTERN) /* compare */
{
p -= delta;
delta /= 2; /* make delta half */
if (delta <= 0) /* exit if delta is 0 */
{ /* page aligned addr */
memTop = (char *)((int)p & ~(VM_PAGE_SIZE - 1));
found = TRUE;
break;
}
}
for (ix=0; ix<N_TIMES; ix++) /* restore */
*((int *)p + ix) = temp[ix];
}
if (!found) /* we are fooled by write-back external cache */
memTop = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE);
/* copy the global descriptor table from RAM/ROM to RAM */
bcopy ((char *)sysGdt, (char *)pSysGdt, GDT_ENTRIES * sizeof(GDT));
*(short *)&gdtr[0] = GDT_ENTRIES * sizeof(GDT) - 1;
*(int *)&gdtr[2] = (int)pSysGdt;
/*
* We assume that there are no memory mapped IO addresses
* above the "memTop" if INCLUDE_PCI is not defined.
* Thus we set the "limit" to get the General Protection Fault
* when the memory above the "memTop" is accessed.
*/
#ifndef INCLUDE_PCI
{
GDT *pGdt = pSysGdt;
int limit = (((int)memTop) / 0x1000 - 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 (gdtr);
#if (VM_PAGE_SIZE == PAGE_SIZE_4KB)
pMmu = &sysPhysMemDesc[3]; /* 4th entry: above 1.5MB upper memory */
pMmu->len = (UINT)memTop - (UINT)pMmu->physicalAddr;
#else /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */
pMmu = &sysPhysMemDesc[1]; /* 2nd entry: above 4MB upper memory */
pMmu->len = (UINT)memTop - (UINT)pMmu->physicalAddr;
#endif /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */
memTopPhys = memTop; /* set the real memory size */
return (memTop);
}
/*******************************************************************************
*
* 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;
if ((int)&end < 0x100000) /* this is for bootrom */
memTop = (char *)0xa0000;
}
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;
int ix;
int iy;
int iz;
char buf[ROM_SIGNATURE_SIZE];
short *pSrc;
short *pDst;
VM_ENABLE (FALSE); /* disbale MMU */
/* decide a destination RAM address and the entry point */
if ((int)&end > 0x100000)
{
pDst = (short *)RAM_HIGH_ADRS; /* copy it in lower mem */
pEntry = (FUNCPTR)(RAM_HIGH_ADRS + ROM_WARM_HIGH);
}
else
{
pDst = (short *)RAM_LOW_ADRS; /* copy it in upper mem */
pEntry = (FUNCPTR)(RAM_LOW_ADRS + ROM_WARM_LOW);
}
/* disable 16-bit memory access */
#ifdef INCLUDE_ULTRA
sysOutByte (IO_ADRS_ULTRA + 4, sysInByte (IO_ADRS_ULTRA + 4) | 0x80);
sysOutByte (IO_ADRS_ULTRA + 5, sysInByte (IO_ADRS_ULTRA + 5) & ~0x80);
#endif /* INCLUDE_ULTRA */
#ifdef INCLUDE_ELC
sysOutByte (IO_ADRS_ELC + 5, sysInByte (IO_ADRS_ELC + 5) & ~0x80);
#endif /* INCLUDE_ELC */
/* copy EPROM to RAM and jump, if there is a VxWorks EPROM */
for (ix = 0; ix < NELEMENTS(sysRomBase); ix++)
{
bcopyBytes ((char *)sysRomBase[ix], buf, ROM_SIGNATURE_SIZE);
if (strncmp (sysRomSignature, buf, ROM_SIGNATURE_SIZE) == 0)
{
for (iy = 0; iy < 1024; iy++)
{
*sysRomBase[ix] = iy; /* map the moveable window */
pSrc = (short *)((int)sysRomBase[ix] + 0x200);
for (iz = 0; iz < 256; iz++)
*pDst++ = *pSrc++;
}
sysClkDisable (); /* disable the system clock interrupt */
sysIntInitPIC (); /* reset the used interrupt controllers */
(*pEntry) (startType);
}
}
#ifdef INCLUDE_FD
if (sysWarmType == SYS_WARM_FD)
{
IMPORT int dosFsDrvNum;
fdDrv (FD_INT_VEC, FD_INT_LVL); /* initialize floppy disk */
if (dosFsDrvNum == ERROR)
dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */
if (usrFdConfig (sysWarmFdDrive, sysWarmFdType, "/vxboot/") == ERROR)
{
printErr ("usrFdConfig failed.\n");
return (ERROR);
}
}
#endif /* INCLUDE_FD */
#ifdef INCLUDE_ATA
if (sysWarmType == SYS_WARM_ATA)
{
ATA_RESOURCE *pAtaResource = &ataResources[sysWarmAtaCtrl];
IMPORT int dosFsDrvNum;
if (ataDrv (sysWarmAtaCtrl, pAtaResource->drives,
pAtaResource->intVector, pAtaResource->intLevel,
pAtaResource->configType, pAtaResource->semTimeout,
pAtaResource->wdgTimeout) == ERROR) /* initialize ATA/IDE disk */
{
printErr ("Could not initialize.\n");
return (ERROR);
}
if (dosFsDrvNum == ERROR)
dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */
if (usrAtaConfig (sysWarmAtaCtrl, sysWarmAtaDrive, "/vxboot/") == ERROR)
{
printErr ("usrAtaConfig failed.\n");
return (ERROR);
}
}
#endif /* INCLUDE_ATA */
#ifdef INCLUDE_TFFS
if (sysWarmType == SYS_WARM_TFFS)
{
IMPORT int dosFsDrvNum;
tffsDrv (); /* initialize TFFS */
if (dosFsDrvNum == ERROR)
dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */
if (usrTffsConfig (sysWarmTffsDrive, FALSE, "/vxboot/") == ERROR)
{
printErr ("usrTffsConfig failed.\n");
return (ERROR);
}
}
#endif /* INCLUDE_TFFS */
#if (defined(INCLUDE_FD) || defined(INCLUDE_ATA) || defined(INCLUDE_TFFS))
if ((sysWarmType == SYS_WARM_FD) || (sysWarmType == SYS_WARM_ATA) ||
(sysWarmType == SYS_WARM_TFFS))
{
int fd;
if ((fd = open ("/vxboot/bootrom.sys", O_RDWR, 0644)) == ERROR)
{
if ((fd = open ("/vxboot/bootrom.dat", O_RDWR, 0644)) == ERROR)
{
printErr ("Can't open \"%s\"\n", "bootrom.{sys,dat}");
return (ERROR);
}
if (read (fd, (char *)pDst, 0x20) == ERROR) /* a.out header */
{
printErr ("Error during read file: %x\n", errnoGet ());
return (ERROR);
}
}
/* read text and data, write them to the memory */
if (read (fd, (char *)pDst, 0x98000) == ERROR)
{
printErr ("Error during read file: %x\n", errnoGet ());
return (ERROR);
}
close (fd);
sysClkDisable (); /* disable the system clock interrupt */
sysIntInitPIC (); /* reset the used interrupt controllers */
(*pEntry) (startType);
}
#endif /* (INCLUDE_FD) || (INCLUDE_ATA) || (INCLUDE_TFFS) */
intLock ();
#ifdef INCLUDE_ELC
elcdetach (0);
#endif /* INCLUDE_ELC */
#ifdef INCLUDE_ULTRA
ultradetach (0);
#endif /* INCLUDE_ULTRA */
sysClkDisable ();
sysWait ();
sysOutByte (COMMAND_8042, 0xfe); /* assert SYSRESET */
sysWait ();
sysOutByte (COMMAND_8042, 0xff); /* NULL command */
sysReboot (); /* crash the global descriptor table */
return (OK); /* in case we ever continue from ROM monitor */
}
/*******************************************************************************
*
* sysIntInitPIC - initialize the interrupt controller
*
* This routine initializes the interrupt controller.
*
* RETURNS: N/A
*
* ARGSUSED0
*/
LOCAL void sysIntInitPIC (void)
{
#if defined(VIRTUAL_WIRE_MODE)
{
int addrLo; /* page aligned Local APIC Base Address */
int lengthLo; /* length of Local APIC registers */
loApicInit ();
i8259Init ();
/* add an entry to the sysMmuPhysDesc[] for Local APIC */
addrLo = ((int)loApicBase / PAGE_SIZE) * PAGE_SIZE;
lengthLo = (int)loApicBase - addrLo + LOAPIC_LENGTH;
if ((lengthLo % PAGE_SIZE) != 0)
lengthLo = (lengthLo / PAGE_SIZE + 1) * PAGE_SIZE;
sysMmuMapAdd ((void *)addrLo, lengthLo,
VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_IO);
}
#elif defined(SYMMETRIC_IO_MODE)
{
int addrLo; /* page aligned Local APIC Base Address */
int addrIo; /* page aligned IO APIC Base Address */
int lengthLo; /* length of Local APIC registers */
int lengthIo; /* length of IO APIC registers */
loApicInit ();
i8259Init ();
ioApicInit ();
/* add an entry to the sysMmuPhysDesc[] for Local APIC and IO APIC */
addrLo = ((int)loApicBase / PAGE_SIZE) * PAGE_SIZE;
lengthLo = (int)loApicBase - addrLo + LOAPIC_LENGTH;
if ((lengthLo % PAGE_SIZE) != 0)
lengthLo = (lengthLo / PAGE_SIZE + 1) * PAGE_SIZE;
addrIo = ((int)ioApicBase / PAGE_SIZE) * PAGE_SIZE;
lengthIo = (int)ioApicBase - addrIo + IOAPIC_LENGTH;
if ((lengthIo % PAGE_SIZE) != 0)
lengthIo = (lengthIo / PAGE_SIZE + 1) * PAGE_SIZE;
if (addrLo == addrIo)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -