ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ioapic.c
Go to the documentation of this file.
00001 /* $Id$
00002  *
00003  * COPYRIGHT:             See COPYING in the top level directory
00004  * PROJECT:               ReactOS kernel
00005  * FILE:                  hal/halx86/mp/ioapic.c
00006  * PURPOSE:               
00007  * PROGRAMMER:            
00008  */
00009 
00010 /* INCLUDES *****************************************************************/
00011 
00012 #include <hal.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* GLOBALS *****************************************************************/
00017 
00018 MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
00019 ULONG IRQCount = 0;                             /* Number of IRQs  */
00020 ULONG IrqApicMap[MAX_IRQ_SOURCE];
00021 
00022 UCHAR BUSMap[MAX_BUS];              /* Map of all buses in the system */
00023 UCHAR PCIBUSMap[MAX_BUS];           /* Map of all PCI buses in the system */
00024 
00025 IOAPIC_INFO IOAPICMap[MAX_IOAPIC];      /* Map of all I/O APICs in the system */
00026 ULONG IOAPICCount;              /* Number of I/O APICs in the system */
00027 
00028 ULONG IRQVectorMap[MAX_IRQ_SOURCE];             /* IRQ to vector map */
00029 
00030 /* EISA interrupts are always polarity zero and can be edge or level
00031  * trigger depending on the ELCR value.  If an interrupt is listed as
00032  * EISA conforming in the MP table, that means its trigger type must
00033  * be read in from the ELCR */
00034 
00035 #define default_EISA_trigger(idx)   (EISA_ELCR_Read(IRQMap[idx].SrcBusIrq))
00036 #define default_EISA_polarity(idx)  (0)
00037 
00038 /* ISA interrupts are always polarity zero edge triggered,
00039  * when listed as conforming in the MP table. */
00040 
00041 #define default_ISA_trigger(idx)    (0)
00042 #define default_ISA_polarity(idx)   (0)
00043 
00044 /* PCI interrupts are always polarity one level triggered,
00045  * when listed as conforming in the MP table. */
00046 
00047 #define default_PCI_trigger(idx)    (1)
00048 #define default_PCI_polarity(idx)   (1)
00049 
00050 /* MCA interrupts are always polarity zero level triggered,
00051  * when listed as conforming in the MP table. */
00052 
00053 #define default_MCA_trigger(idx)    (1)
00054 #define default_MCA_polarity(idx)   (0)
00055 
00056 /***************************************************************************/
00057 
00058 extern VOID Disable8259AIrq(ULONG irq);
00059 ULONG IOAPICRead(ULONG Apic, ULONG Offset);
00060 VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
00061 
00062 /* FUNCTIONS ***************************************************************/
00063 
00064 /*
00065  * EISA Edge/Level control register, ELCR
00066  */
00067 static ULONG EISA_ELCR_Read(ULONG irq)
00068 {
00069    if (irq < 16) 
00070    {
00071       PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
00072       return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
00073    }
00074    DPRINT("Broken MPtable reports ISA irq %d\n", irq);
00075    return 0;
00076 }
00077 
00078 static ULONG 
00079 IRQPolarity(ULONG idx)
00080 {
00081    ULONG bus = IRQMap[idx].SrcBusId;
00082    ULONG polarity;
00083 
00084    /*
00085     * Determine IRQ line polarity (high active or low active):
00086     */
00087    switch (IRQMap[idx].IrqFlag & 3)
00088    {
00089       case 0: /* conforms, ie. bus-type dependent polarity */
00090          {
00091             switch (BUSMap[bus])
00092         {
00093            case MP_BUS_ISA: /* ISA pin */
00094           polarity = default_ISA_polarity(idx);
00095           break;
00096           
00097            case MP_BUS_EISA: /* EISA pin */
00098           polarity = default_EISA_polarity(idx);
00099           break;
00100         
00101            case MP_BUS_PCI: /* PCI pin */
00102           polarity = default_PCI_polarity(idx);
00103           break;
00104 
00105            case MP_BUS_MCA: /* MCA pin */
00106                   polarity = default_MCA_polarity(idx);
00107           break;
00108         
00109            default:
00110           DPRINT("Broken BIOS!!\n");
00111           polarity = 1;
00112         }
00113      }
00114      break;
00115 
00116       case 1: /* high active */
00117      polarity = 0;
00118      break;
00119 
00120       case 2: /* reserved */
00121      DPRINT("Broken BIOS!!\n");
00122      polarity = 1;
00123      break;
00124 
00125       case 3: /* low active */
00126          polarity = 1;
00127      break;
00128 
00129       default: /* invalid */
00130      DPRINT("Broken BIOS!!\n");
00131      polarity = 1;
00132    }
00133    return polarity;
00134 }
00135 
00136 static ULONG 
00137 IRQTrigger(ULONG idx)
00138 {
00139    ULONG bus = IRQMap[idx].SrcBusId;
00140    ULONG trigger;
00141 
00142    /*
00143     * Determine IRQ trigger mode (edge or level sensitive):
00144     */
00145    switch ((IRQMap[idx].IrqFlag >> 2) & 3)
00146    {
00147       case 0: /* conforms, ie. bus-type dependent */
00148      {
00149             switch (BUSMap[bus])
00150         {
00151            case MP_BUS_ISA: /* ISA pin */
00152               trigger = default_ISA_trigger(idx);
00153           break;
00154 
00155            case MP_BUS_EISA: /* EISA pin */
00156           trigger = default_EISA_trigger(idx);
00157           break;
00158         
00159            case MP_BUS_PCI: /* PCI pin */
00160           trigger = default_PCI_trigger(idx);
00161           break;
00162 
00163                case MP_BUS_MCA: /* MCA pin */
00164           trigger = default_MCA_trigger(idx);
00165           break;
00166         
00167                default:
00168                   DPRINT("Broken BIOS!!\n");
00169           trigger = 1;
00170         }
00171      }
00172      break;
00173 
00174       case 1: /* edge */
00175      trigger = 0;
00176      break;
00177 
00178       case 2: /* reserved */
00179      DPRINT("Broken BIOS!!\n");
00180      trigger = 1;
00181      break;
00182 
00183       case 3: /* level */
00184      trigger = 1;
00185      break;
00186     
00187       default: /* invalid */
00188      DPRINT("Broken BIOS!!\n");
00189      trigger = 0;                   
00190    }
00191    return trigger;
00192 }
00193 
00194 static ULONG 
00195 Pin2Irq(ULONG idx,
00196     ULONG apic,
00197     ULONG pin)
00198 {
00199    ULONG irq, i;
00200    ULONG bus = IRQMap[idx].SrcBusId;
00201 
00202    /*
00203     * Debugging check, we are in big trouble if this message pops up!
00204     */
00205    if (IRQMap[idx].DstApicInt != pin) 
00206    {
00207       DPRINT("broken BIOS or MPTABLE parser, ayiee!!\n");
00208    }
00209 
00210    switch (BUSMap[bus])
00211    {
00212       case MP_BUS_ISA: /* ISA pin */
00213       case MP_BUS_EISA:
00214       case MP_BUS_MCA:
00215     irq = IRQMap[idx].SrcBusIrq;
00216     break;
00217 
00218       case MP_BUS_PCI: /* PCI pin */
00219      /*
00220       * PCI IRQs are mapped in order
00221       */
00222      i = irq = 0;
00223      while (i < apic)
00224      {
00225         irq += IOAPICMap[i++].EntryCount;
00226      }
00227      irq += pin;
00228      break;
00229     
00230       default:
00231      DPRINT("Unknown bus type %d.\n",bus);
00232      irq = 0;
00233    }
00234    return irq;
00235 }
00236 
00237 static ULONG 
00238 AssignIrqVector(ULONG irq)
00239 {
00240 #if 0
00241    static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;
00242 #endif
00243    ULONG vector;
00244    /* There may already have been assigned a vector for this IRQ */
00245    vector = IRQVectorMap[irq];
00246    if (vector > 0)
00247    {
00248       return vector;
00249    }
00250 #if 0
00251    if (current_vector > FIRST_SYSTEM_VECTOR) 
00252    {
00253       vector_offset++;
00254       current_vector = FIRST_DEVICE_VECTOR + vector_offset;
00255    } 
00256    else if (current_vector == FIRST_SYSTEM_VECTOR) 
00257    {
00258       DPRINT1("Ran out of interrupt sources!");
00259       ASSERT(FALSE);
00260    }
00261 
00262    vector = current_vector;
00263    IRQVectorMap[irq] = vector;
00264    current_vector += 8;
00265    return vector;
00266 #else
00267    vector = IRQ2VECTOR(irq);
00268    IRQVectorMap[irq] = vector;
00269    return vector;
00270 #endif
00271 }
00272 
00273 /*
00274  * Find the IRQ entry number of a certain pin.
00275  */
00276 static ULONG 
00277 IOAPICGetIrqEntry(ULONG apic,
00278           ULONG pin,
00279           ULONG type)
00280 {
00281    ULONG i;
00282 
00283    for (i = 0; i < IRQCount; i++)
00284    {
00285       if (IRQMap[i].IrqType == type &&
00286       (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&
00287       IRQMap[i].DstApicInt == pin)
00288       {
00289          return i;
00290       }
00291    }
00292    return -1;
00293 }
00294 
00295 
00296 VOID 
00297 IOAPICSetupIrqs(VOID)
00298 {
00299    IOAPIC_ROUTE_ENTRY entry;
00300    ULONG apic, pin, idx, irq, first_notcon = 1, vector, trigger;
00301 
00302    DPRINT("Init IO_APIC IRQs\n");
00303 
00304    /* Setup IRQ to vector translation map */
00305    memset(&IRQVectorMap, 0, sizeof(IRQVectorMap));
00306 
00307    for (apic = 0; apic < IOAPICCount; apic++) 
00308    {
00309       for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++) 
00310       {
00311          /*
00312       * add it to the IO-APIC irq-routing table
00313       */
00314      memset(&entry,0,sizeof(entry));
00315 
00316      entry.delivery_mode = (APIC_DM_LOWEST >> 8);
00317      entry.dest_mode = 1;  /* logical delivery */
00318      entry.mask = 1;       /* disable IRQ */
00319          entry.dest.logical.logical_dest = 0;
00320 
00321      idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);
00322      if (idx == (ULONG)-1)
00323      {
00324         if (first_notcon) 
00325         {
00326            DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);
00327            first_notcon = 0;
00328         } 
00329         else 
00330         {
00331            DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);
00332             }
00333         continue;
00334      }
00335 
00336          trigger = IRQTrigger(idx);
00337      entry.polarity = IRQPolarity(idx);
00338 
00339      if (trigger) 
00340      {
00341         entry.trigger = 1;
00342      }
00343 
00344      irq = Pin2Irq(idx, apic, pin);
00345 
00346      vector = AssignIrqVector(irq);
00347      entry.vector = vector;
00348 
00349      DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);
00350 
00351          if (irq == 0)
00352          {
00353             /* Mask timer IRQ */
00354             entry.mask = 1;
00355          }
00356 
00357          if ((apic == 0) && (irq < 16))
00358      {
00359         Disable8259AIrq(irq);
00360      }
00361          IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
00362      IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
00363 
00364      IrqApicMap[irq] = apic;
00365 
00366      DPRINT("Vector %x, Pin %x, Irq %x\n", vector, pin, irq);
00367       }
00368    }
00369 }
00370 
00371 static VOID 
00372 IOAPICClearPin(ULONG Apic, ULONG Pin)
00373 {
00374    IOAPIC_ROUTE_ENTRY Entry;
00375 
00376    DPRINT("IOAPICClearPin(Apic %d, Pin %d\n", Apic, Pin);
00377    /*
00378     * Disable it in the IO-APIC irq-routing table
00379     */
00380    memset(&Entry, 0, sizeof(Entry));
00381    Entry.mask = 1;
00382 
00383    IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
00384    IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
00385 }
00386 
00387 static VOID 
00388 IOAPICClear(ULONG Apic)
00389 {
00390    ULONG Pin;
00391 
00392    for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)
00393    {
00394      IOAPICClearPin(Apic, Pin);
00395    }
00396 }
00397 
00398 static VOID 
00399 IOAPICClearAll(VOID)
00400 {
00401    ULONG Apic;
00402 
00403    for (Apic = 0; Apic < IOAPICCount; Apic++)
00404    {
00405       IOAPICClear(Apic);
00406    }
00407 }
00408 
00409 VOID 
00410 IOAPICEnable(VOID)
00411 {
00412    ULONG i, tmp;
00413 
00414    /* Setup IRQ to vector translation map */
00415    memset(&IRQVectorMap, 0, sizeof(IRQVectorMap));
00416 
00417    /*
00418     * The number of IO-APIC IRQ registers (== #pins):
00419     */
00420    for (i = 0; i < IOAPICCount; i++) 
00421    {
00422       tmp = IOAPICRead(i, IOAPIC_VER);
00423       IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;
00424    }
00425 
00426    /*
00427     * Do not trust the IO-APIC being empty at bootup
00428     */
00429    IOAPICClearAll();
00430 }
00431 
00432 VOID 
00433 IOAPICSetupIds(VOID)
00434 {
00435   ULONG tmp, apic, i;
00436   UCHAR old_id;
00437   
00438   /*
00439    * Set the IOAPIC ID to the value stored in the MPC table.
00440    */
00441   for (apic = 0; apic < IOAPICCount; apic++) 
00442   {
00443     
00444     /* Read the register 0 value */
00445     tmp = IOAPICRead(apic, IOAPIC_ID);
00446     
00447     old_id = IOAPICMap[apic].ApicId;
00448     
00449     if (IOAPICMap[apic].ApicId >= 0xf) 
00450     {
00451       DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
00452           apic, IOAPICMap[apic].ApicId);
00453       DPRINT1("... fixing up to %d. (tell your hw vendor)\n", 
00454           GET_IOAPIC_ID(tmp));
00455       IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);
00456     }
00457     
00458     /*
00459      * We need to adjust the IRQ routing table
00460      * if the ID changed.
00461      */
00462     if (old_id != IOAPICMap[apic].ApicId)
00463     {
00464       for (i = 0; i < IRQCount; i++)
00465       {
00466     if (IRQMap[i].DstApicId == old_id)
00467     {
00468       IRQMap[i].DstApicId = IOAPICMap[apic].ApicId;
00469     }
00470       }
00471     }
00472     
00473     /*
00474      * Read the right value from the MPC table and
00475      * write it into the ID register.
00476      */
00477     DPRINT("Changing IO-APIC physical APIC ID to %d\n",
00478        IOAPICMap[apic].ApicId);
00479     
00480     tmp &= ~IOAPIC_ID_MASK;
00481     tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId);
00482 
00483     IOAPICWrite(apic, IOAPIC_ID, tmp);
00484     
00485     /*
00486      * Sanity check
00487      */
00488     tmp = IOAPICRead(apic, 0);
00489     if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId) 
00490     {
00491       DPRINT1("Could not set I/O APIC ID!\n");
00492       ASSERT(FALSE);
00493     }
00494   }
00495 }
00496 
00497 /* This is performance critical and should probably be done in assembler */
00498 VOID IOAPICMaskIrq(ULONG Irq)
00499 {
00500    IOAPIC_ROUTE_ENTRY Entry;
00501    ULONG Apic = IrqApicMap[Irq];
00502 
00503    *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
00504    *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);
00505    Entry.dest.logical.logical_dest &= ~(1 << KeGetCurrentProcessorNumber());
00506    if (Entry.dest.logical.logical_dest == 0)
00507    {
00508       Entry.mask = 1;
00509    }
00510    IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));
00511    IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));
00512 }
00513 
00514 /* This is performance critical and should probably be done in assembler */
00515 VOID IOAPICUnmaskIrq(ULONG Irq)
00516 {
00517    IOAPIC_ROUTE_ENTRY Entry;
00518    ULONG Apic = IrqApicMap[Irq];
00519 
00520    *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
00521    *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);
00522    Entry.dest.logical.logical_dest |= 1 << KeGetCurrentProcessorNumber();
00523    Entry.mask = 0;
00524    IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));
00525    IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));
00526 }
00527 
00528 VOID IOAPICDump(VOID)
00529 {
00530    ULONG apic, i;
00531    ULONG reg0, reg1, reg2=0;
00532 
00533    DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
00534    for (i = 0; i < IOAPICCount; i++) 
00535    {
00536       DbgPrint("Number of IO-APIC #%d registers: %d.\n",
00537            IOAPICMap[i].ApicId,
00538                IOAPICMap[i].EntryCount);
00539    }
00540 
00541    /*
00542     * We are a bit conservative about what we expect.  We have to
00543     * know about every hardware change ASAP.
00544     */
00545    DbgPrint("Testing the IO APIC.......................\n");
00546 
00547    for (apic = 0; apic < IOAPICCount; apic++) 
00548    {
00549       reg0 = IOAPICRead(apic, IOAPIC_ID);
00550       reg1 = IOAPICRead(apic, IOAPIC_VER);
00551       if (GET_IOAPIC_VERSION(reg1) >= 0x10) 
00552       {
00553          reg2 = IOAPICRead(apic, IOAPIC_ARB);
00554       }
00555 
00556       DbgPrint("\n");
00557       DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
00558       DbgPrint(".... register #00: %08X\n", reg0);
00559       DbgPrint(".......    : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
00560       if (reg0 & 0xF0FFFFFF) 
00561       {
00562          DbgPrint("  WARNING: Unexpected IO-APIC\n");
00563       }
00564 
00565       DbgPrint(".... register #01: %08X\n", reg1);
00566       i = GET_IOAPIC_MRE(reg1);
00567 
00568       DbgPrint(".......     : max redirection entries: %04X\n", i);
00569       if ((i != 0x0f) &&    /* older (Neptune) boards */
00570       (i != 0x17) &&    /* typical ISA+PCI boards */
00571       (i != 0x1b) &&    /* Compaq Proliant boards */
00572       (i != 0x1f) &&    /* dual Xeon boards */
00573           (i != 0x22) &&   /* bigger Xeon boards */
00574       (i != 0x2E) &&
00575       (i != 0x3F)) 
00576       {
00577          DbgPrint("  WARNING: Unexpected IO-APIC\n");
00578       }
00579 
00580       i = GET_IOAPIC_VERSION(reg1);
00581       DbgPrint(".......     : IO APIC version: %04X\n", i);
00582       if ((i != 0x01) &&    /* 82489DX IO-APICs */
00583       (i != 0x10) &&    /* oldest IO-APICs */
00584       (i != 0x11) &&    /* Pentium/Pro IO-APICs */
00585       (i != 0x13))      /* Xeon IO-APICs */
00586       {
00587          DbgPrint("  WARNING: Unexpected IO-APIC\n");
00588       }
00589 
00590       if (reg1 & 0xFF00FF00) 
00591       {
00592          DbgPrint("  WARNING: Unexpected IO-APIC\n");
00593       }
00594 
00595       if (GET_IOAPIC_VERSION(reg1) >= 0x10) 
00596       {
00597      DbgPrint(".... register #02: %08X\n", reg2);
00598      DbgPrint(".......     : arbitration: %02X\n",
00599               GET_IOAPIC_ARB(reg2));
00600      if (reg2 & 0xF0FFFFFF) 
00601      {
00602             DbgPrint("  WARNING: Unexpected IO-APIC\n");
00603          }
00604       }
00605 
00606       DbgPrint(".... IRQ redirection table:\n");
00607       DbgPrint(" NR Log Phy Mask Trig IRR Pol"
00608            " Stat Dest Deli Vect:   \n");
00609 
00610       for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++) 
00611       {
00612          IOAPIC_ROUTE_ENTRY entry;
00613 
00614      *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
00615      *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
00616 
00617      DbgPrint(" %02x %03X %02X  ",
00618           i,
00619           entry.dest.logical.logical_dest,
00620           entry.dest.physical.physical_dest);
00621 
00622          DbgPrint("%C    %C    %1d  %C    %C    %C     %03X    %02X\n",
00623           (entry.mask == 0) ? 'U' : 'M',            // Unmasked/masked
00624           (entry.trigger == 0) ? 'E' : 'L',         // Edge/level sensitive
00625           entry.irr,
00626           (entry.polarity == 0) ? 'H' : 'L',        // Active high/active low
00627           (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
00628           (entry.dest_mode == 0) ? 'P' : 'L',       // Physical logical
00629           entry.delivery_mode,
00630           entry.vector);
00631       }
00632    }
00633 
00634    DbgPrint(".................................... done.\n");
00635 }
00636 
00637 VOID
00638 HaliReconfigurePciInterrupts(VOID)
00639 {
00640    ULONG i;
00641 
00642    for (i = 0; i < IRQCount; i++)
00643    {
00644       if (BUSMap[IRQMap[i].SrcBusId] == MP_BUS_PCI)
00645       {
00646          DPRINT("%02x: IrqType %02x, IrqFlag %02x, SrcBusId %02x, SrcBusIrq %02x"
00647             ", DstApicId %02x, DstApicInt %02x\n",
00648             i, IRQMap[i].IrqType, IRQMap[i].IrqFlag, IRQMap[i].SrcBusId, 
00649             IRQMap[i].SrcBusIrq, IRQMap[i].DstApicId, IRQMap[i].DstApicInt);
00650 
00651      HalSetBusDataByOffset(PCIConfiguration, 
00652                                    IRQMap[i].SrcBusId, 
00653                        (IRQMap[i].SrcBusIrq >> 2) & 0x1f, 
00654                        &IRQMap[i].DstApicInt, 
00655                        0x3c /*PCI_INTERRUPT_LINE*/, 
00656                        1);
00657 
00658       }
00659    }
00660 }
00661 
00662 VOID Disable8259AIrq(ULONG irq)
00663 {
00664     UCHAR tmp;
00665 
00666     if (irq >= 8) 
00667     {
00668        tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
00669        tmp |= (1 << (irq - 8));
00670        WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
00671     } 
00672     else 
00673     {
00674        tmp = READ_PORT_UCHAR((PUCHAR)0x21);
00675        tmp |= (1 << irq);
00676        WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
00677     }
00678 }
00679 
00680 ULONG IOAPICRead(ULONG Apic, ULONG Offset)
00681 {
00682   PULONG Base;
00683 
00684   Base = (PULONG)IOAPICMap[Apic].ApicAddress;
00685   *Base = Offset;
00686   return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));
00687 }
00688 
00689 VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)
00690 {
00691   PULONG Base;
00692 
00693   Base = (PULONG)IOAPICMap[Apic].ApicAddress;
00694   *Base = Offset;
00695   *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value;
00696 }
00697 
00698 /* EOF */

Generated on Sun May 27 2012 04:28:44 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.