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

📄 init.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Permedia3 Sample Display Driver
// init.c
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This module contains all of the code necessary to locate the Permedia3
// device on the PCI bus, read it's configuration, and initialize it. This
// code also initializes the global structures with the memory mapped IO
// addresses, video memory information and other configuration information
// from the PCI bus and the card's ROM. 

#include "pch.h"  // Precompiled header support. 
#include "const.h"
#include "debug.h"
#include "struct.h"
#include "proto.h"
#include "global.h"
#include "register.h"

// This global contains all of the configuration information about the
// device.

PERM3_CONFIG g_Config;

// Internal prototypes. These functions are not exposed outside this module.

static BOOL 
PciFindDevice(
  USHORT             VendorId,
  USHORT             DeviceId,
  PULONG             BusNumber,
  PPCI_SLOT_NUMBER   SlotNumber,
  PPCI_COMMON_CONFIG CommonConfig
  );

static BOOL
InitializeRom();

static BOOL
CopyRomTable(
  LPVOID RomImage
  );

static BOOL
GenerateRomTable();

static void
ResetChip();

static void
ProcessInitializationTable();

BOOL
InitializeHardware()
{
  // InitializeHardware
  // This top-level function coordinates locating the device, initializing it, 
  // reading it's configuration data, and making sure the driver data
  // structures are initialize correcrtly. We expect to only be called ONCE.

  // Local variables.

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

  Enter(L"InitializeHardware");

  // Scour the PCI bus for our device.

  if (PciFindDevice(VENDOR_ID,
                    DEVICE_ID,
                    &g_Config.PciBusNumber,
                    &g_Config.PciSlotNumber,
                    &g_Config.PciCommonConfig)) {

    if (InitializeRegisters()) {

      if (InitializeRom()) {

        if (InitializeVideoMem()) {

          if (InitializeModes()) {

            if (InitializeDMA()) {

              if (InitializeInterrupts()) {

                FnRetVal = TRUE;

                Message(L"Permedia3 hardware initialized.\n");
              }
              else {
                Error(L"Unable to initialize interrupts!\n");
              }
            }
            else {
              Error(L"Unable to initialize Permedia3 DMA support!\n");
            }
          }
          else {
            Error(L"Unable to initialize Permedia3 display mode handler!\n");
          }
        }
        else {
          Error(L"Unable to initialize Permedia3 video memory!\n");
        }
      }
      else {
        Error(L"Unable to initialize Permedia3 register access!\n");
      }
    }
    else {
      Error(L"Unable to read Permedia3 ROM initialization table!\n");
    }
  }
  else {
    Error(L"Unable to locate Permedia3 device on PCI bus!\n");
  }

  Exit(L"InitializeHardware");

  return FnRetVal;
}

BOOL 
PciFindDevice(
  USHORT             VendorId,
  USHORT             DeviceId,
  PULONG             BusNumber,
  PPCI_SLOT_NUMBER   SlotNumber,
  PPCI_COMMON_CONFIG CommonConfig
  )
{
  // PciFindDevice
  // Examines all functions on all devices on all buses on the PCI subsystem
  // for the matching vendor and device ID. Returns the bus number, slot
  // number, and the configuration if the device is found (function returns
  // TRUE.)

  // Local variables.

  BOOL FnRetVal = FALSE;  // Return value for this function.
  ULONG Bus, Device, Function, ConfigLength;

  // Check parameters.

  // VendorId and DeviceId can be anything.
  AssertWritePtr(BusNumber, sizeof(ULONG));
  AssertWritePtr(SlotNumber, sizeof(PCI_SLOT_NUMBER));
  AssertWritePtr(CommonConfig, sizeof(PCI_COMMON_CONFIG));

  Enter(L"PciFindDevice");

  // Iterate over all buses, devices and functions.

  for (Bus = 0; Bus < PCI_MAX_BUS; Bus++) {

    for (Device = 0; Device < PCI_MAX_DEVICES; Device++) {
            
      SlotNumber->u.bits.DeviceNumber = Device;

      for (Function = 0; Function < PCI_MAX_FUNCTION; Function++) {
                
        SlotNumber->u.bits.FunctionNumber = Function;

        // Check out this bus/device/function. It might be the one we are
        // looking for.

        ConfigLength = HalGetBusData(PCIConfiguration, 
                                     Bus, 
                                     SlotNumber->u.AsULONG,
                                     CommonConfig,
                                     sizeof(PCI_COMMON_CONFIG));

        if (ConfigLength == 0 || 
            CommonConfig->VendorID == 0xFFFF) {

          // !TODO! Nothing here. Unfortuantly, I don't know if we can stop at
          // this point.

          break;
        }

        if (VendorId == CommonConfig->VendorID &&
            DeviceId == CommonConfig->DeviceID) {

          // This is it. Save the bus number and set our loop variables to
          // break us out of the loops.

          *BusNumber = Bus;

          Function = PCI_MAX_FUNCTION;
          Device = PCI_MAX_DEVICES;
          Bus = PCI_MAX_BUS;

          FnRetVal = TRUE;

          Message(L"Located Permedia3 on PCI bus.\n");
        }
      }
    }
  }
  
  Exit(L"PciFindDevice");

  return FnRetVal;
}

BOOL
InitializeRom()
{
  // InitializeRom
  // This function reads the initialization sequence stored in the Permedia3's
  // Rom BIOS. This is a table of register writes that will be used later (once
  // we have initialized access to the Memory Region 0) to initialize the chip.

  // Local variables.

  BOOL FnRetVal = FALSE;  // Return value for this function.
  PHYSICAL_ADDRESS RomBus;
  PHYSICAL_ADDRESS RomPhysical;
  ULONG AddressSpace;
  PVOID RomImage = NULL;

  Enter(L"InitializeRom");

  if (g_Config.PciCommonConfig.u.type0.ROMBaseAddress != 0) {

    // Try to enable access to the rom.

    g_Config.PciCommonConfig.u.type0.ROMBaseAddress |= b_CFGRomAddr_AccessDecodeEnable;

    if (HalSetBusDataByOffset(PCIConfiguration,
                              g_Config.PciBusNumber,
                              g_Config.PciSlotNumber.u.AsULONG,
                              &g_Config.PciCommonConfig.u.type0.ROMBaseAddress,
                              r_CFGRomAddr,
                              sizeof(ULONG)) != sizeof(ULONG)) {

      // We can continue if we fail: we will genertae an initialization table
      // ourselves.

      Message(L"Unable to send bus configuration to Permedia3!\n");
    }

    // See if we have successfully enabled rom access.

    if (g_Config.PciCommonConfig.u.type0.ROMBaseAddress & b_CFGRomAddr_AccessDecodeEnable) {

      // VirtualAlloc enough virtual addresses in order to map the whole rom
      // region into virtual space.

      RomImage = VirtualAlloc(NULL,  // System locates virtual space
                              ROM_SIZE,
                              MEM_RESERVE,
                              PAGE_NOACCESS);

      if (RomImage != NULL) {

        // Use HalTranslateBusAddress to turn the PCI address into a physical
        // address. Essentially, this is finding out what physical address the
        // processor needs to issue to the PCI bus to get to the given PCI
        // address.

        AddressSpace = 0;  // Memory mapped, not port mapped
        RomPhysical.QuadPart = 0;
        RomBus.LowPart = g_Config.PciCommonConfig.u.type0.ROMBaseAddress;
        RomBus.HighPart = 0;
        if (HalTranslateBusAddress(PCIBus,
                                   g_Config.PciBusNumber,
                                   RomBus,
                                   &AddressSpace,
                                   &RomPhysical)) {

          // Now, actually map the physical address to a virtual address. We
          // need to shift the physcial address right because when
          // PAGE_PHYSICAL is specified, VirtualCopy expects the high 32 bits
          // of a 40 bit address. The shift essentially sets those high 8 bits
          // to 0.

          if (VirtualCopy(RomImage,
                          (LPVOID)(RomPhysical.LowPart >> 8),
                          ROM_SIZE,
                          PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)) {  

            Message(L"ROM initialization table sucessfully mapped.\n");

            // Locate and copy the initialization table into g_Config.

            FnRetVal = CopyRomTable(RomImage);

            // Free the ROM mapping. We do not need it any longer. (Don't care
            // if this call fails.)

            VirtualFree(RomImage,
                        0,  // Must == 0 because we specify MEM_RELEASE

⌨️ 快捷键说明

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