VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c@ 85788

Last change on this file since 85788 was 85718, checked in by vboxsync, 5 years ago

Devices/EFI: Merge edk-stable202005 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
1/** @file
2 I/O APIC library.
3
4 I/O APIC library assumes I/O APIC is enabled. It does not
5 handles cases where I/O APIC is disabled.
6
7 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include <Base.h>
13
14#include <Library/IoApicLib.h>
15
16#include <Library/DebugLib.h>
17#include <Library/PcdLib.h>
18#include <Library/IoLib.h>
19#include <Library/LocalApicLib.h>
20
21#include <Register/IoApic.h>
22
23/**
24 Read a 32-bit I/O APIC register.
25
26 If Index is >= 0x100, then ASSERT().
27
28 @param Index Specifies the I/O APIC register to read.
29
30 @return The 32-bit value read from the I/O APIC register specified by Index.
31**/
32UINT32
33EFIAPI
34IoApicRead (
35 IN UINTN Index
36 )
37{
38 ASSERT (Index < 0x100);
39 MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index);
40 return MmioRead32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET);
41}
42
43/**
44 Write a 32-bit I/O APIC register.
45
46 If Index is >= 0x100, then ASSERT().
47
48 @param Index Specifies the I/O APIC register to write.
49 @param Value Specifies the value to write to the I/O APIC register specified by Index.
50
51 @return The 32-bit value written to I/O APIC register specified by Index.
52**/
53UINT32
54EFIAPI
55IoApicWrite (
56 IN UINTN Index,
57 IN UINT32 Value
58 )
59{
60 ASSERT (Index < 0x100);
61 MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index);
62 return MmioWrite32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET, Value);
63}
64
65/**
66 Set the interrupt mask of an I/O APIC interrupt.
67
68 If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT().
69
70 @param Irq Specifies the I/O APIC interrupt to enable or disable.
71 @param Enable If TRUE, then enable the I/O APIC interrupt specified by Irq.
72 If FALSE, then disable the I/O APIC interrupt specified by Irq.
73**/
74VOID
75EFIAPI
76IoApicEnableInterrupt (
77 IN UINTN Irq,
78 IN BOOLEAN Enable
79 )
80{
81 IO_APIC_VERSION_REGISTER Version;
82 IO_APIC_REDIRECTION_TABLE_ENTRY Entry;
83
84 Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX);
85 ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0);
86 ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry);
87
88 Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2);
89 Entry.Bits.Mask = Enable ? 0 : 1;
90 IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low);
91}
92
93/**
94 Configures an I/O APIC interrupt.
95
96 Configure an I/O APIC Redirection Table Entry to deliver an interrupt in physical
97 mode to the Local APIC of the currently executing CPU. The default state of the
98 entry is for the interrupt to be disabled (masked). IoApicEnableInterrupts() must
99 be used to enable(unmask) the I/O APIC Interrupt.
100
101 If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT().
102 If Vector >= 0x100, then ASSERT().
103 If DeliveryMode is not supported, then ASSERT().
104
105 @param Irq Specifies the I/O APIC interrupt to initialize.
106 @param Vector The 8-bit interrupt vector associated with the I/O APIC
107 Interrupt. Must be in the range 0x10..0xFE.
108 @param DeliveryMode A 3-bit value that specifies how the recept of the I/O APIC
109 interrupt is handled. The only supported values are:
110 0: IO_APIC_DELIVERY_MODE_FIXED
111 1: IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY
112 2: IO_APIC_DELIVERY_MODE_SMI
113 4: IO_APIC_DELIVERY_MODE_NMI
114 5: IO_APIC_DELIVERY_MODE_INIT
115 7: IO_APIC_DELIVERY_MODE_EXTINT
116 @param LevelTriggered TRUE specifies a level triggered interrupt.
117 FALSE specifies an edge triggered interrupt.
118 @param AssertionLevel TRUE specified an active high interrupt.
119 FALSE specifies an active low interrupt.
120**/
121VOID
122EFIAPI
123IoApicConfigureInterrupt (
124 IN UINTN Irq,
125 IN UINTN Vector,
126 IN UINTN DeliveryMode,
127 IN BOOLEAN LevelTriggered,
128 IN BOOLEAN AssertionLevel
129 )
130{
131 IO_APIC_VERSION_REGISTER Version;
132 IO_APIC_REDIRECTION_TABLE_ENTRY Entry;
133
134 Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX);
135 ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0);
136 ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry);
137 ASSERT (Vector <= 0xFF);
138 ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3);
139
140 Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2);
141 Entry.Bits.Vector = (UINT8)Vector;
142 Entry.Bits.DeliveryMode = (UINT32)DeliveryMode;
143 Entry.Bits.DestinationMode = 0;
144 Entry.Bits.Polarity = AssertionLevel ? 0 : 1;
145 Entry.Bits.TriggerMode = LevelTriggered ? 1 : 0;
146 Entry.Bits.Mask = 1;
147 IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low);
148
149 Entry.Uint32.High = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1);
150 Entry.Bits.DestinationID = GetApicId ();
151 IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1, Entry.Uint32.High);
152}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette