⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
                        MEM_RELEASE);

            // Reset the chip.

            ResetChip();

            // Now, we need to send the initialization table.

            ProcessInitializationTable();
          }
          else {
            Error(L"Unable to map physical address to virtual address!\n");
          }
        }
        else {
          Error(L"Unable to translate bus address to physical address!\n");
        }
      }
      else {
        Error(L"Unable to allocate virtual address for ROM!\n");
      }
    }
  }

  if (FnRetVal == FALSE) {

    Message(L"Rom access is disabled. Generating initialization table.\n");

    FnRetVal = GenerateRomTable();
  }

  Exit(L"InitializeRom");

  return FnRetVal;
}

BOOL
CopyRomTable(
  LPVOID RomImage
  )
{
  // CopyRomTable
  // This function takes the address of the Permedia3 ROM. It reads the ROM and
  // extracts the register initialization table into the g_Config global.

  // Local variables.

  BOOL FnRetVal = FALSE;  // Return value for this function.
  ULONG * Table;
  USHORT TableOffset;
  ULONG TableHeader;
  ULONG TableBytes;

  Enter(L"CopyRomTable");

  g_Config.InitializationTableEntries = 0;

  // Read the 2 byte BIOS version number.

  g_Config.BiosVersionMajorNumber = *((BYTE *)RomImage + ROM_MAJOR_VER_OFFSET);
  g_Config.BiosVersionMinorNumber = *((BYTE *)RomImage + ROM_MINOR_VER_OFFSET);

  // There is double indirection to the ROM initialization table. We first look
  // at a constant offset from ther beginning of ROM to get the offset of the
  // table.

  TableOffset = *(USHORT *)((BYTE *)RomImage + ROM_TABLE_OFFSET_OFFSET);
  Table = (ULONG *)((BYTE *)RomImage + TableOffset);
    
  // The table header (32 bits) has an identification code and a count
  // of the number of entries in the table.

  TableHeader = *Table++;

  // The top two bytes of the parition header should be 3D Labs PCI Vendor Id.

  while ((TableHeader >> 16) == VENDOR_ID) {

    // The 2nd lowest byte is the BIOS partition type.   

    switch ((TableHeader >> 8) & 0xFF) {
        
    case 0:

      // BIOS partition 0. This BIOS region holds the memory timings for the
      // Permedia3 chip.

      // Get the number of register address & data pairs from the header. It's
      // the low byte.

      g_Config.InitializationTableEntries = TableHeader & 0x000000FF;

      Assert(g_Config.InitializationTableEntries != 0);
               
      // Allocate memory for the table. Note that each entry is 2 4 byte
      // values, or the number of bytes in the table is 8 times the number
      // of entries.

      TableBytes = g_Config.InitializationTableEntries * 8;
      g_Config.InitializationTable = (ULONG *)SystemAlloc(TableBytes);

      if (g_Config.InitializationTable != NULL) {

        // Copy the initilization sequence from ROM to system memory.

        memcpy(g_Config.InitializationTable,
               Table,
               TableBytes);

        FnRetVal = TRUE;
      }
      else {
        Error(L"Unable to allocate system memory for register initialization table.\n");
      }

      break;

    case 1:

      // BIOS partition 1. This BIOS region holds extended clock settings for
      // PXRX chips.

      g_Config.HaveExtendedClocks = TRUE;

      g_Config.PXRXCoreClock = ((*Table++) & 0x00FFFFFF) * 1000 * 1000;

      g_Config.PXRXMemoryClock = *Table++;
      g_Config.PXRXMemoryClockSrc = (g_Config.PXRXMemoryClock >> 28) << 4;
      g_Config.PXRXMemoryClock = (g_Config.PXRXMemoryClock & 0x00FFFFFF) * 1000 * 1000;

      g_Config.PXRXSetupClock = *Table++;
      g_Config.PXRXSetupClockSrc = (g_Config.PXRXSetupClock >> 28) << 4;
      g_Config.PXRXSetupClock = (g_Config.PXRXSetupClock & 0x00FFFFFF) * 1000 * 1000;

      g_Config.PXRXGammaClock = ((*Table++) & 0x00FFFFFF) * 1000 * 1000;

      g_Config.PXRXCoreClockAlt = ((*Table++) & 0x00FFFFFF) * 1000 * 1000;
 
      break;
        
    default:
      Error(L"Found unknown BIOS ROM partition type.\n");
      break; 
    }

    // Get next partition header.

    TableHeader = *Table++;
  }

  Exit(L"CopyRomTable");

  return FnRetVal;
}

BOOL
GenerateRomTable()
{
  // GenerateRomTable
  // This function is called if access to the Permedia3 ROM BIOS table cannot
  // be established. It atempts to load some sensible default values into
  // the initialization table.

  // Local constants.

  const ULONG TableEntries = 4;
  const ULONG TableBytes = sizeof(ULONG) * TableEntries * 2;

  // Local variables.

  BOOL FnRetVal = FALSE;  // Return value for this function.

  Enter(L"GenerateRomTable");

#ifdef CEPC

  // No video BIOS information available...

  g_Config.BiosVersionMajorNumber = 0;
  g_Config.BiosVersionMinorNumber = 0;

  // No extended settings are currently used...

  g_Config.HaveExtendedClocks = FALSE;

  g_Config.InitializationTableEntries = TableEntries;
  g_Config.InitializationTable = (ULONG *)SystemAlloc(TableBytes);

  if (g_Config.InitializationTable != NULL) {

    // The system BIOS has already initialized the card, and we have yet to
    // reset it, so we can read out the values we need for our initialization
    // table to feed it back into the card after reset.

    g_Config.InitializationTable[0] = r_LocalMemCaps;
    g_Config.InitializationTable[1] = ReadRegUlong(r_LocalMemCaps);

    g_Config.InitializationTable[2] = r_LocalMemControl;
    g_Config.InitializationTable[3] = ReadRegUlong(r_LocalMemControl);

    g_Config.InitializationTable[4] = r_LocalMemRefresh;
    g_Config.InitializationTable[5] = ReadRegUlong(r_LocalMemRefresh);

    g_Config.InitializationTable[6] = r_LocalMemTiming;
    g_Config.InitializationTable[7] = ReadRegUlong(r_LocalMemTiming);
    
    FnRetVal = TRUE;
  }
  else {

    Error(L"Unable to allocate system memory for register initialization table.\n");
  }

#else

  Error(L"GenerateRomTable does not work on platforms with no system BIOS!\n");

#endif

  Exit(L"GenerateRomTable");

  return FnRetVal;
}

void
ResetChip()
{
  // ResetChip
  // This function sends a software reset to the chip, so that we can begin
  // with a clean slate. Once the reset is sent, we poll the ResetStatus
  // register to wait for it to finish. We also insure that the VGA is
  // turned off.

  Enter(L"ResetChip");

  // Writing any value to ResetStatus should cause a reset.

  WriteRegUlong(r_ResetStatus, 0);

  // Wait for the reset to complete.

  while (ReadMaskedRegUlong(r_ResetStatus, b_ResetStatus_SoftwareResetFlag) != 0);

  // Now, make sure that P3 is not in VGA mode, start by unlocking the VGA.
  // The values 0x3D and 0xDB are arbitrary and mandated by the Permedia3
  // Reference Guide, pg. 4-122.

  WriteVgaReg(r_VGALockExtended1Reg, 0x3D);
  WriteVgaReg(r_VGALockExtended2Reg, 0xDB);

  // Disable the VGA.

  WriteMaskedVgaReg(r_VGAControlReg, b_VGAControlReg_EnableVGADisplay, 0);

  // Finish by re-locking the extended VGA registers. We need only write
  // anything but the magic combination.

  WriteVgaReg(r_VGALockExtended1Reg, 0);

  Exit(L"ResetChip");
}

void
ProcessInitializationTable()
{
  // ProcessInitializationTable
  // By the time that the InitializeRegister call is made, we should have
  // already read or generated an initialization table. This function sends
  // that table to the hardware.

  // Local variables.

  ULONG * Table = g_Config.InitializationTable;
  ULONG TableEntries = g_Config.InitializationTableEntries;
  ULONG Register;
  ULONG Data;

  Enter(L"ProcessInitializationTable");

  WaitForInputFIFO(TableEntries);

  while (TableEntries--) {

    Register = *Table++;
    Data = *Table++;

    WriteRegUlong(Register, Data);
  }

  Exit(L"ProcessInitializationTable");
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -