8259.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 663 行 · 第 1/2 页

C
663
字号
    This  - Protocol instance pointer.
    Mode  - 
    Mask  -

  Returns:
    EFI_SUCCESS       - 8259 programmed
    EFI_DEVICE_ERROR  - Error writting to 8259

--*/
// TODO:    EdgeLevel - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
{
  if (Mode == mMode) {
    return EFI_SUCCESS;
  }

  if (Mode == Efi8259LegacyMode) {
    //
    // Save the protected mode mask
    //
    Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel);

    if (Mask != NULL) {
      //
      // Update the Mask for the new mode
      //
      mLegacyModeMask = *Mask;
    }

    if (EdgeLevel != NULL) {
      //
      // Update the Edge/Level triggered mask for the new mode
      //
      mLegacyModeEdgeLevel = *EdgeLevel;
    }

    mMode = Mode;

    //
    // Enable Interrupts
    //
    Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);

    return EFI_SUCCESS;
  }

  if (Mode == Efi8259ProtectedMode) {
    //
    // Save the legacy mode mask
    //
    Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);
    //
    // Always force Timer to be enabled after return from 16-bit code.
    // This always insures that on next entry, timer is counting.
    //
    mLegacyModeMask &= 0xFFFE;

    if (Mask != NULL) {
      //
      // Update the Mask for the new mode
      //
      mProtectedModeMask = *Mask;
    }

    if (EdgeLevel != NULL) {
      //
      // Update the Edge/Level triggered mask for the new mode
      //
      mProtectedModeEdgeLevel = *EdgeLevel;
    }

    mMode = Mode;

    //
    // Enable Interrupts
    //
    Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

    return EFI_SUCCESS;
  }

  return EFI_INVALID_PARAMETER;
}

EFI_STATUS
EFIAPI
Interrupt8259GetVector (
  IN  EFI_LEGACY_8259_PROTOCOL  *This,
  IN  EFI_8259_IRQ              Irq,
  OUT UINT8                     *Vector
  )
/*++

  Routine Description:
    Convert from IRQ to processor interrupt vector number.

  Arguments:
    This    - Protocol instance pointer.
    Irq     - 8259 IRQ0 - IRQ15
    Vector  - Processor vector number that matches Irq

  Returns:
    EFI_SUCCESS           - The Vector matching Irq is returned
    EFI_INVALID_PARAMETER - Irq not valid

--*/
{
  if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {
    return EFI_INVALID_PARAMETER;
  }

  if (Irq <= Efi8259Irq7) {
    *Vector = (UINT8) (mMasterBase + Irq);
  } else {
    *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
Interrupt8259EnableIrq (
  IN  EFI_LEGACY_8259_PROTOCOL  *This,
  IN  EFI_8259_IRQ              Irq,
  IN  BOOLEAN                   LevelTriggered
  )
/*++

  Routine Description:
    Enable Irq by unmasking interrupt in 8259

  Arguments:
    This    - Protocol instance pointer.
    Irq     - 8259 IRQ0 - IRQ15

  Returns:
    EFI_SUCCESS           - Irq enabled on 8259
    EFI_INVALID_PARAMETER - Irq not valid

--*/
// TODO:    LevelTriggered - add argument and description to function comment
{
  if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {
    return EFI_INVALID_PARAMETER;
  }

  mProtectedModeMask &= ~(1 << Irq);
  if (LevelTriggered) {
    mProtectedModeEdgeLevel |= (1 << Irq);
  } else {
    mProtectedModeEdgeLevel &= ~(1 << Irq);
  }

  Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
Interrupt8259DisableIrq (
  IN  EFI_LEGACY_8259_PROTOCOL  *This,
  IN  EFI_8259_IRQ              Irq
  )
/*++

  Routine Description:
    Disable Irq by masking interrupt in 8259

  Arguments:
    This    - Protocol instance pointer.
    Irq     - 8259 IRQ0 - IRQ15

  Returns:
    EFI_SUCCESS           - Irq disabled on 8259
    EFI_INVALID_PARAMETER - Irq not valid

--*/
{
  if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {
    return EFI_INVALID_PARAMETER;
  }

  mProtectedModeMask |= (1 << Irq);
  mProtectedModeEdgeLevel &= ~(1 << Irq);

  Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
Interrupt8259GetInterruptLine (
  IN  EFI_LEGACY_8259_PROTOCOL  *This,
  IN  EFI_HANDLE                PciHandle,
  OUT UINT8                     *Vector
  )
/*++

  Routine Description:
    PciHandle represents a PCI config space of a PCI function. Vector 
    represents Interrupt Pin (from PCI config space) and it is the data
    that is programmed into the Interrupt Line (from the PCI config space)
    register.

  Arguments:
    This      - Protocol instance pointer.
    PciHandle - PCI function to return vector for 
    Vector    - Vector for fucntion that matches 

  Returns:
    EFI_SUCCESS           - A valid Vector is returned
    EFI_INVALID_PARAMETER - PciHandle not valid

--*/
{
  return EFI_UNSUPPORTED;
}

EFI_STATUS
EFIAPI
Interrupt8259EndOfInterrupt (
  IN  EFI_LEGACY_8259_PROTOCOL  *This,
  IN  EFI_8259_IRQ              Irq
  )
/*++

  Routine Description:
    Send an EOI to 8259

  Arguments:
    This    - Protocol instance pointer.
    Irq     - 8259 IRQ0 - IRQ15

  Returns:
    EFI_SUCCESS           - EOI successfully sent to 8259
    EFI_INVALID_PARAMETER - Irq not valid

--*/
{
  if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {
    return EFI_INVALID_PARAMETER;
  }

  if (Irq >= Efi8259Irq8) {
    IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
  }

  IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);

  return EFI_SUCCESS;
}

//
// Delclare Legacy 8259 Driver Entry Point
//
EFI_DRIVER_ENTRY_POINT (Install8259)

//
// Legacy 8259 Driver Entry Point
//
EFI_STATUS
EFIAPI
Install8259 (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
/*++

Routine Description:
  

Arguments:

  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

Returns:

  EFI_SUCCESS - Legacy 8259  Protocol Installed

--*/
// TODO:    ImageHandle - add argument and description to function comment
// TODO:    SystemTable - add argument and description to function comment
{
  EFI_STATUS   Status;
  EFI_8259_IRQ Irq;

  //
  // Initializwe the EFI Driver Library
  //
  EfiInitializeDriverLib (ImageHandle, SystemTable);

  //
  // Find the CPU I/O Protocol
  //
  Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &mCpuIo);
  ASSERT_EFI_ERROR (Status);

  //
  // Clear all pending interrupt
  //
  for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
    Interrupt8259EndOfInterrupt (&m8259, Irq);
  }

  //
  // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
  //
  Status = Interrupt8259SetVectorBase (&m8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);

  //
  // Set all 8259 interrupts to edge triggered and disabled
  //
  Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);

  //
  // Install 8259 Protocol onto a new handle
  //
  Status = gBS->InstallProtocolInterface (
                  &m8259Handle,
                  &gEfiLegacy8259ProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &m8259
                  );

  return Status;
}

⌨️ 快捷键说明

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