]> git.proxmox.com Git - mirror_edk2.git/blame - PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
Add directory for the new added Language Library.
[mirror_edk2.git] / PcAtChipsetPkg / 8259InterruptControllerDxe / 8259.c
CommitLineData
1166d068 1/**@file\r
2 This contains the installation function for the driver.\r
3 \r
90b8b0ec 4Copyright (c) 2005 - 2009, Intel Corporation \r
1166d068 5All rights reserved. This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
13**/\r
14\r
15#include "8259.h"\r
16\r
1166d068 17//\r
90b8b0ec 18// Global for the Legacy 8259 Protocol that is produced by this driver\r
1166d068 19//\r
20EFI_LEGACY_8259_PROTOCOL m8259 = {\r
21 Interrupt8259SetVectorBase,\r
22 Interrupt8259GetMask,\r
23 Interrupt8259SetMask,\r
24 Interrupt8259SetMode,\r
25 Interrupt8259GetVector,\r
26 Interrupt8259EnableIrq,\r
27 Interrupt8259DisableIrq,\r
28 Interrupt8259GetInterruptLine,\r
29 Interrupt8259EndOfInterrupt\r
30};\r
31\r
32//\r
33// Global for the handle that the Legacy 8259 Protocol is installed\r
34//\r
35EFI_HANDLE m8259Handle = NULL;\r
36\r
37UINT8 mMasterBase = 0xff;\r
38UINT8 mSlaveBase = 0xff;\r
39EFI_8259_MODE mMode = Efi8259ProtectedMode;\r
40UINT16 mProtectedModeMask = 0xffff;\r
41UINT16 mLegacyModeMask = 0x06b8;\r
42UINT16 mProtectedModeEdgeLevel = 0x0000;\r
43UINT16 mLegacyModeEdgeLevel = 0x0000;\r
44\r
45//\r
46// Worker Functions\r
47//\r
90b8b0ec 48\r
49/**\r
50 Write to mask and edge/level triggered registers of master and slave PICs.\r
51\r
52 @param[in] Mask low byte for master PIC mask register,\r
53 high byte for slave PIC mask register.\r
54 @param[in] EdgeLevel low byte for master PIC edge/level triggered register,\r
55 high byte for slave PIC edge/level triggered register.\r
56\r
57**/\r
1166d068 58VOID\r
59Interrupt8259WriteMask (\r
60 IN UINT16 Mask,\r
61 IN UINT16 EdgeLevel\r
62 )\r
1166d068 63{\r
64 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, (UINT8) Mask);\r
65 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, (UINT8) (Mask >> 8));\r
66 IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER, (UINT8) EdgeLevel);\r
67 IoWrite8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE, (UINT8) (EdgeLevel >> 8));\r
68}\r
69\r
1166d068 70/**\r
90b8b0ec 71 Read from mask and edge/level triggered registers of master and slave PICs.\r
1166d068 72\r
90b8b0ec 73 @param[out] Mask low byte for master PIC mask register,\r
74 high byte for slave PIC mask register.\r
75 @param[out] EdgeLevel low byte for master PIC edge/level triggered register,\r
76 high byte for slave PIC edge/level triggered register.\r
1166d068 77\r
78**/\r
90b8b0ec 79VOID\r
80Interrupt8259ReadMask (\r
81 OUT UINT16 *Mask,\r
82 OUT UINT16 *EdgeLevel\r
83 )\r
1166d068 84{\r
a694b670 85 UINT16 MasterValue;\r
86 UINT16 SlaveValue;\r
87\r
1166d068 88 if (Mask != NULL) {\r
a694b670 89 MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);\r
90 SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);\r
91\r
92 *Mask = (UINT16) (MasterValue | (SlaveValue << 8));\r
1166d068 93 }\r
94\r
95 if (EdgeLevel != NULL) {\r
a694b670 96 MasterValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);\r
97 SlaveValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);\r
98\r
99 *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));\r
1166d068 100 }\r
101}\r
90b8b0ec 102\r
1166d068 103//\r
90b8b0ec 104// Legacy 8259 Protocol Interface Functions\r
1166d068 105//\r
1166d068 106\r
90b8b0ec 107/**\r
108 Sets the base address for the 8259 master and slave PICs.\r
1166d068 109\r
90b8b0ec 110 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
111 @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.\r
112 @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.\r
1166d068 113\r
90b8b0ec 114 @retval EFI_SUCCESS The 8259 PIC was programmed successfully.\r
115 @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.\r
1166d068 116\r
117**/\r
90b8b0ec 118EFI_STATUS\r
119EFIAPI\r
120Interrupt8259SetVectorBase (\r
121 IN EFI_LEGACY_8259_PROTOCOL *This,\r
122 IN UINT8 MasterBase,\r
123 IN UINT8 SlaveBase\r
124 )\r
1166d068 125{\r
126 UINT8 Mask;\r
127\r
90b8b0ec 128 //\r
129 // Set vector base for slave PIC\r
130 //\r
1166d068 131 if (SlaveBase != mSlaveBase) {\r
132 mSlaveBase = SlaveBase;\r
133\r
134 //\r
90b8b0ec 135 // Initialization sequence is needed for setting vector base.\r
136 //\r
137\r
138 //\r
139 // Preserve interrtup mask register before initialization sequence\r
140 // because it will be cleared during intialization\r
1166d068 141 //\r
142 Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);\r
90b8b0ec 143\r
144 //\r
145 // ICW1: cascade mode, ICW4 write required\r
146 //\r
1166d068 147 IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);\r
90b8b0ec 148\r
149 //\r
150 // ICW2: new vector base (must be multiple of 8)\r
151 //\r
1166d068 152 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);\r
90b8b0ec 153\r
154 //\r
155 // ICW3: slave indentification code must be 2\r
156 //\r
1166d068 157 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);\r
90b8b0ec 158\r
159 //\r
160 // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor\r
161 //\r
1166d068 162 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);\r
90b8b0ec 163\r
164 //\r
165 // Restore interrupt mask register\r
166 //\r
1166d068 167 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);\r
168 }\r
169\r
90b8b0ec 170 //\r
171 // Set vector base for master PIC\r
172 //\r
1166d068 173 if (MasterBase != mMasterBase) {\r
174 mMasterBase = MasterBase;\r
175\r
176 //\r
90b8b0ec 177 // Initialization sequence is needed for setting vector base.\r
178 //\r
179\r
180 //\r
181 // Preserve interrtup mask register before initialization sequence\r
182 // because it will be cleared during intialization\r
1166d068 183 //\r
184 Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);\r
90b8b0ec 185\r
186 //\r
187 // ICW1: cascade mode, ICW4 write required\r
188 //\r
1166d068 189 IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);\r
90b8b0ec 190\r
191 //\r
192 // ICW2: new vector base (must be multiple of 8)\r
193 //\r
1166d068 194 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);\r
90b8b0ec 195\r
196 //\r
197 // ICW3: slave PIC is cascaded on IRQ2\r
198 //\r
1166d068 199 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);\r
90b8b0ec 200\r
201 //\r
202 // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor\r
203 //\r
1166d068 204 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);\r
90b8b0ec 205\r
206 //\r
207 // Restore interrupt mask register\r
208 //\r
1166d068 209 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);\r
210 }\r
211\r
212 IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x20);\r
213 IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x20);\r
214\r
215 return EFI_SUCCESS;\r
216}\r
217\r
90b8b0ec 218/**\r
219 Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.\r
220\r
221 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
222 @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.\r
223 @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.\r
224 @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.\r
225 @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.\r
226\r
227 @retval EFI_SUCCESS The 8259 PIC was programmed successfully.\r
228 @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.\r
229\r
230**/\r
1166d068 231EFI_STATUS\r
232EFIAPI\r
233Interrupt8259GetMask (\r
90b8b0ec 234 IN EFI_LEGACY_8259_PROTOCOL *This,\r
1166d068 235 OUT UINT16 *LegacyMask, OPTIONAL\r
236 OUT UINT16 *LegacyEdgeLevel, OPTIONAL\r
237 OUT UINT16 *ProtectedMask, OPTIONAL\r
238 OUT UINT16 *ProtectedEdgeLevel OPTIONAL\r
239 )\r
1166d068 240{\r
241 if (LegacyMask != NULL) {\r
242 *LegacyMask = mLegacyModeMask;\r
243 }\r
244\r
245 if (LegacyEdgeLevel != NULL) {\r
246 *LegacyEdgeLevel = mLegacyModeEdgeLevel;\r
247 }\r
248\r
249 if (ProtectedMask != NULL) {\r
250 *ProtectedMask = mProtectedModeMask;\r
251 }\r
252\r
253 if (ProtectedEdgeLevel != NULL) {\r
254 *ProtectedEdgeLevel = mProtectedModeEdgeLevel;\r
255 }\r
256\r
257 return EFI_SUCCESS;\r
258}\r
259\r
1166d068 260/**\r
90b8b0ec 261 Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.\r
1166d068 262\r
90b8b0ec 263 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
264 @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.\r
265 @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.\r
266 @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.\r
267 @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.\r
1166d068 268\r
90b8b0ec 269 @retval EFI_SUCCESS The 8259 PIC was programmed successfully.\r
270 @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.\r
1166d068 271\r
272**/\r
90b8b0ec 273EFI_STATUS\r
274EFIAPI\r
275Interrupt8259SetMask (\r
276 IN EFI_LEGACY_8259_PROTOCOL *This,\r
277 IN UINT16 *LegacyMask, OPTIONAL\r
278 IN UINT16 *LegacyEdgeLevel, OPTIONAL\r
279 IN UINT16 *ProtectedMask, OPTIONAL\r
280 IN UINT16 *ProtectedEdgeLevel OPTIONAL\r
281 )\r
1166d068 282{\r
283 if (LegacyMask != NULL) {\r
284 mLegacyModeMask = *LegacyMask;\r
285 }\r
286\r
287 if (LegacyEdgeLevel != NULL) {\r
288 mLegacyModeEdgeLevel = *LegacyEdgeLevel;\r
289 }\r
290\r
291 if (ProtectedMask != NULL) {\r
292 mProtectedModeMask = *ProtectedMask;\r
293 }\r
294\r
295 if (ProtectedEdgeLevel != NULL) {\r
296 mProtectedModeEdgeLevel = *ProtectedEdgeLevel;\r
297 }\r
298\r
299 return EFI_SUCCESS;\r
300}\r
301\r
1166d068 302/**\r
90b8b0ec 303 Sets the mode of the PICs.\r
1166d068 304\r
90b8b0ec 305 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
306 @param[in] Mode 16-bit real or 32-bit protected mode.\r
307 @param[in] Mask The value with which to set the interrupt mask.\r
308 @param[in] EdgeLevel The value with which to set the edge/level mask.\r
1166d068 309\r
90b8b0ec 310 @retval EFI_SUCCESS The mode was set successfully.\r
311 @retval EFI_INVALID_PARAMETER The mode was not set.\r
1166d068 312\r
313**/\r
90b8b0ec 314EFI_STATUS\r
315EFIAPI\r
316Interrupt8259SetMode (\r
317 IN EFI_LEGACY_8259_PROTOCOL *This,\r
318 IN EFI_8259_MODE Mode,\r
319 IN UINT16 *Mask, OPTIONAL\r
320 IN UINT16 *EdgeLevel OPTIONAL\r
321 )\r
1166d068 322{\r
323 if (Mode == mMode) {\r
324 return EFI_SUCCESS;\r
325 }\r
326\r
327 if (Mode == Efi8259LegacyMode) {\r
328 //\r
90b8b0ec 329 // In Efi8259ProtectedMode, mask and edge/level trigger registers should\r
330 // be changed through this protocol, so we can track them in the\r
331 // corresponding module variables.\r
1166d068 332 //\r
333 Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel);\r
334\r
335 if (Mask != NULL) {\r
336 //\r
337 // Update the Mask for the new mode\r
338 //\r
339 mLegacyModeMask = *Mask;\r
340 }\r
341\r
342 if (EdgeLevel != NULL) {\r
343 //\r
344 // Update the Edge/Level triggered mask for the new mode\r
345 //\r
346 mLegacyModeEdgeLevel = *EdgeLevel;\r
347 }\r
348\r
349 mMode = Mode;\r
350\r
351 //\r
90b8b0ec 352 // Write new legacy mode mask/trigger level\r
1166d068 353 //\r
354 Interrupt8259SetVectorBase (This, LEGACY_MODE_BASE_VECTOR_MASTER, LEGACY_MODE_BASE_VECTOR_SLAVE);\r
355\r
356 //\r
357 // Enable Interrupts\r
358 //\r
359 Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);\r
360\r
361 return EFI_SUCCESS;\r
362 }\r
363\r
364 if (Mode == Efi8259ProtectedMode) {\r
365 //\r
90b8b0ec 366 // Save the legacy mode mask/trigger level\r
1166d068 367 //\r
368 Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);\r
369 //\r
370 // Always force Timer to be enabled after return from 16-bit code.\r
371 // This always insures that on next entry, timer is counting.\r
372 //\r
373 mLegacyModeMask &= 0xFFFE;\r
374\r
375 if (Mask != NULL) {\r
376 //\r
377 // Update the Mask for the new mode\r
378 //\r
379 mProtectedModeMask = *Mask;\r
380 }\r
381\r
382 if (EdgeLevel != NULL) {\r
383 //\r
384 // Update the Edge/Level triggered mask for the new mode\r
385 //\r
386 mProtectedModeEdgeLevel = *EdgeLevel;\r
387 }\r
388\r
389 mMode = Mode;\r
390\r
391 //\r
90b8b0ec 392 // Write new protected mode mask/trigger level\r
1166d068 393 //\r
394 Interrupt8259SetVectorBase (This, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);\r
395\r
396 //\r
397 // Enable Interrupts\r
398 //\r
399 Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);\r
400\r
401 return EFI_SUCCESS;\r
402 }\r
403\r
404 return EFI_INVALID_PARAMETER;\r
405}\r
406\r
90b8b0ec 407/**\r
408 Translates the IRQ into a vector.\r
409\r
410 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
411 @param[in] Irq IRQ0-IRQ15.\r
412 @param[out] Vector The vector that is assigned to the IRQ.\r
413\r
414 @retval EFI_SUCCESS The Vector that matches Irq was returned.\r
415 @retval EFI_INVALID_PARAMETER Irq is not valid.\r
416\r
417**/\r
1166d068 418EFI_STATUS\r
419EFIAPI\r
420Interrupt8259GetVector (\r
421 IN EFI_LEGACY_8259_PROTOCOL *This,\r
422 IN EFI_8259_IRQ Irq,\r
423 OUT UINT8 *Vector\r
424 )\r
1166d068 425{\r
426 if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {\r
427 return EFI_INVALID_PARAMETER;\r
428 }\r
429\r
430 if (Irq <= Efi8259Irq7) {\r
431 *Vector = (UINT8) (mMasterBase + Irq);\r
432 } else {\r
433 *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));\r
434 }\r
435\r
436 return EFI_SUCCESS;\r
437}\r
438\r
1166d068 439/**\r
90b8b0ec 440 Enables the specified IRQ.\r
1166d068 441\r
90b8b0ec 442 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
443 @param[in] Irq IRQ0-IRQ15.\r
444 @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.\r
1166d068 445\r
90b8b0ec 446 @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.\r
447 @retval EFI_INVALID_PARAMETER The Irq is not valid.\r
1166d068 448\r
449**/\r
90b8b0ec 450EFI_STATUS\r
451EFIAPI\r
452Interrupt8259EnableIrq (\r
453 IN EFI_LEGACY_8259_PROTOCOL *This,\r
454 IN EFI_8259_IRQ Irq,\r
455 IN BOOLEAN LevelTriggered\r
456 )\r
1166d068 457{\r
458 if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {\r
459 return EFI_INVALID_PARAMETER;\r
460 }\r
461\r
a694b670 462 mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));\r
1166d068 463 if (LevelTriggered) {\r
a694b670 464 mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 << Irq));\r
1166d068 465 } else {\r
a694b670 466 mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));\r
1166d068 467 }\r
468\r
469 Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);\r
470\r
471 return EFI_SUCCESS;\r
472}\r
473\r
1166d068 474/**\r
90b8b0ec 475 Disables the specified IRQ.\r
1166d068 476\r
90b8b0ec 477 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
478 @param[in] Irq IRQ0-IRQ15.\r
1166d068 479\r
90b8b0ec 480 @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.\r
481 @retval EFI_INVALID_PARAMETER The Irq is not valid.\r
1166d068 482\r
483**/\r
90b8b0ec 484EFI_STATUS\r
485EFIAPI\r
486Interrupt8259DisableIrq (\r
487 IN EFI_LEGACY_8259_PROTOCOL *This,\r
488 IN EFI_8259_IRQ Irq\r
489 )\r
1166d068 490{\r
491 if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {\r
492 return EFI_INVALID_PARAMETER;\r
493 }\r
494\r
90b8b0ec 495 mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));\r
496\r
a694b670 497 mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));\r
1166d068 498\r
499 Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);\r
500\r
501 return EFI_SUCCESS;\r
502}\r
503\r
90b8b0ec 504/**\r
505 Reads the PCI configuration space to get the interrupt number that is assigned to the card.\r
506\r
507 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
508 @param[in] PciHandle PCI function for which to return the vector.\r
509 @param[out] Vector IRQ number that corresponds to the interrupt line.\r
510\r
511 @retval EFI_SUCCESS The interrupt line value was read successfully.\r
512\r
513**/\r
1166d068 514EFI_STATUS\r
515EFIAPI\r
516Interrupt8259GetInterruptLine (\r
517 IN EFI_LEGACY_8259_PROTOCOL *This,\r
518 IN EFI_HANDLE PciHandle,\r
519 OUT UINT8 *Vector\r
520 )\r
1166d068 521{\r
522 return EFI_UNSUPPORTED;\r
523}\r
524\r
1166d068 525/**\r
90b8b0ec 526 Issues the End of Interrupt (EOI) commands to PICs.\r
1166d068 527\r
90b8b0ec 528 @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.\r
529 @param[in] Irq The interrupt for which to issue the EOI command.\r
1166d068 530\r
90b8b0ec 531 @retval EFI_SUCCESS The EOI command was issued.\r
532 @retval EFI_INVALID_PARAMETER The Irq is not valid.\r
1166d068 533\r
534**/\r
90b8b0ec 535EFI_STATUS\r
536EFIAPI\r
537Interrupt8259EndOfInterrupt (\r
538 IN EFI_LEGACY_8259_PROTOCOL *This,\r
539 IN EFI_8259_IRQ Irq\r
540 )\r
1166d068 541{\r
542 if (Irq < Efi8259Irq0 || Irq > Efi8259Irq15) {\r
543 return EFI_INVALID_PARAMETER;\r
544 }\r
545\r
546 if (Irq >= Efi8259Irq8) {\r
547 IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);\r
548 }\r
549\r
550 IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);\r
551\r
552 return EFI_SUCCESS;\r
553}\r
554\r
90b8b0ec 555/**\r
556 Driver Entry point.\r
557\r
558 @param[in] ImageHandle ImageHandle of the loaded driver.\r
559 @param[in] SystemTable Pointer to the EFI System Table.\r
560\r
561 @retval EFI_SUCCESS One or more of the drivers returned a success code.\r
562 @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.\r
563\r
564**/\r
1166d068 565EFI_STATUS\r
566EFIAPI\r
567Install8259 (\r
568 IN EFI_HANDLE ImageHandle,\r
569 IN EFI_SYSTEM_TABLE *SystemTable\r
570 )\r
1166d068 571{\r
572 EFI_STATUS Status;\r
573 EFI_8259_IRQ Irq;\r
574\r
1166d068 575 //\r
576 // Clear all pending interrupt\r
577 //\r
578 for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {\r
579 Interrupt8259EndOfInterrupt (&m8259, Irq);\r
580 }\r
581\r
582 //\r
583 // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70\r
584 //\r
585 Status = Interrupt8259SetVectorBase (&m8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);\r
586\r
587 //\r
588 // Set all 8259 interrupts to edge triggered and disabled\r
589 //\r
590 Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);\r
591\r
592 //\r
593 // Install 8259 Protocol onto a new handle\r
594 //\r
595 Status = gBS->InstallProtocolInterface (\r
596 &m8259Handle,\r
597 &gEfiLegacy8259ProtocolGuid,\r
598 EFI_NATIVE_INTERFACE,\r
599 &m8259\r
600 );\r
1166d068 601 return Status;\r
602}\r
603\r