820ecbb72b4d565822424648fe7e56a658bdb26e
[reactos.git] / hal / halx86 / pci.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/hal/x86/pci.c
6  * PURPOSE:         Interfaces to the PCI bus
7  * PROGRAMMER:      David Welch (welch@mcmail.com)
8  *                  Eric Kohl (ekohl@rz-online.de)
9  * UPDATE HISTORY:
10  *                  05/06/1998: Created
11  *                  17/08/2000: Added preliminary pci bus scanner
12  *                  13/06/2001: Implemented access to pci configuration space
13  */
14
15 /*
16  * NOTES: Sections copied from the Linux pci support
17  */
18
19 /* INCLUDES *****************************************************************/
20
21 #include <roscfg.h>
22 #include <ddk/ntddk.h>
23 #include <bus.h>
24 #ifdef MP
25 #include <mps.h>
26 #endif
27
28
29 #define NDEBUG
30 #include <internal/debug.h>
31
32
33 /* MACROS ******************************************************************/
34
35 /* FIXME These are also defined in drivers/bus/pci/pcidef.h.
36    Maybe put PCI definitions in a central include file??? */
37
38 /* access type 1 macros */
39 #define CONFIG_CMD(bus, dev_fn, where) \
40         (0x80000000 | (((ULONG)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3))
41
42 /* access type 2 macros */
43 #define IOADDR(dev_fn, where) \
44         (0xC000 | (((dev_fn) & 0x1F) << 8) | (where))
45 #define FUNC(dev_fn) \
46         ((((dev_fn) & 0xE0) >> 4) | 0xf0)
47
48 #define  PCI_BASE_ADDRESS_SPACE 0x01    /* 0 = memory, 1 = I/O */
49 #define  PCI_BASE_ADDRESS_SPACE_IO 0x01
50 #define  PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
51 #define  PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
52 #define  PCI_BASE_ADDRESS_MEM_TYPE_32   0x00    /* 32 bit address */
53 #define  PCI_BASE_ADDRESS_MEM_TYPE_1M   0x02    /* Below 1M [obsolete] */
54 #define  PCI_BASE_ADDRESS_MEM_TYPE_64   0x04    /* 64 bit address */
55 #define  PCI_BASE_ADDRESS_MEM_PREFETCH  0x08    /* prefetchable? */
56 #define  PCI_BASE_ADDRESS_MEM_MASK      (~0x0fUL)
57 #define  PCI_BASE_ADDRESS_IO_MASK       (~0x03UL)
58 /* bit 1 is reserved if address_space = 1 */
59
60
61 /* GLOBALS ******************************************************************/
62
63 #define TAG_PCI  TAG('P', 'C', 'I', 'H')
64
65 static ULONG BusConfigType = 0;  /* undetermined config type */
66 static KSPIN_LOCK PciLock;
67
68 /* FUNCTIONS ****************************************************************/
69
70 static NTSTATUS
71 ReadPciConfigUchar(UCHAR Bus,
72                    UCHAR Slot,
73                    UCHAR Offset,
74                    PUCHAR Value)
75 {
76    KIRQL oldIrql;
77
78    switch (BusConfigType)
79      {
80      case 1:
81         KeAcquireSpinLock(&PciLock, &oldIrql);
82         WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
83         *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
84         KeReleaseSpinLock(&PciLock, oldIrql);
85         return STATUS_SUCCESS;
86
87      case 2:
88         KeAcquireSpinLock(&PciLock, &oldIrql);
89         WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
90         WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
91         *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
92         WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
93         KeReleaseSpinLock(&PciLock, oldIrql);
94         return STATUS_SUCCESS;
95      }
96    return STATUS_UNSUCCESSFUL;
97 }
98
99
100 static NTSTATUS
101 ReadPciConfigUshort(UCHAR Bus,
102                     UCHAR Slot,
103                     UCHAR Offset,
104                     PUSHORT Value)
105 {
106    KIRQL oldIrql;
107
108    if ((Offset & 1) != 0)
109      {
110         return STATUS_INVALID_PARAMETER;
111      }
112
113    switch (BusConfigType)
114      {
115      case 1:
116         KeAcquireSpinLock(&PciLock, &oldIrql);
117         WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
118         *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2));
119         KeReleaseSpinLock(&PciLock, oldIrql);
120         return STATUS_SUCCESS;
121
122      case 2:
123         KeAcquireSpinLock(&PciLock, &oldIrql);
124         WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
125         WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
126         *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
127         WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
128         KeReleaseSpinLock(&PciLock, oldIrql);
129         return STATUS_SUCCESS;
130      }
131    return STATUS_UNSUCCESSFUL;
132 }
133
134
135 static NTSTATUS
136 ReadPciConfigUlong(UCHAR Bus,
137                    UCHAR Slot,
138                    UCHAR Offset,
139                    PULONG Value)
140 {
141    KIRQL oldIrql;
142
143    if ((Offset & 3) != 0)
144      {
145         return STATUS_INVALID_PARAMETER;
146      }
147
148    switch (BusConfigType)
149      {
150      case 1:
151         KeAcquireSpinLock(&PciLock, &oldIrql);
152         WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
153         *Value = READ_PORT_ULONG((PULONG)0xCFC);
154         KeReleaseSpinLock(&PciLock, oldIrql);
155         return STATUS_SUCCESS;
156
157      case 2:
158         KeAcquireSpinLock(&PciLock, &oldIrql);
159         WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
160         WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
161         *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
162         WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
163         KeReleaseSpinLock(&PciLock, oldIrql);
164         return STATUS_SUCCESS;
165      }
166    return STATUS_UNSUCCESSFUL;
167 }
168
169
170 static NTSTATUS
171 WritePciConfigUchar(UCHAR Bus,
172                     UCHAR Slot,
173                     UCHAR Offset,
174                     UCHAR Value)
175 {
176    KIRQL oldIrql;
177
178    switch (BusConfigType)
179      {
180      case 1:
181         KeAcquireSpinLock(&PciLock, &oldIrql);
182         WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
183         WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
184         KeReleaseSpinLock(&PciLock, oldIrql);
185         return STATUS_SUCCESS;
186
187      case 2:
188         KeAcquireSpinLock(&PciLock, &oldIrql);
189         WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
190         WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
191         WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
192         WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
193         KeReleaseSpinLock(&PciLock, oldIrql);
194         return STATUS_SUCCESS;
195      }
196    return STATUS_UNSUCCESSFUL;
197 }
198
199
200 static NTSTATUS
201 WritePciConfigUshort(UCHAR Bus,
202                      UCHAR Slot,
203                      UCHAR Offset,
204                      USHORT Value)
205 {
206    KIRQL oldIrql;
207
208    if ((Offset & 1) != 0)
209      {
210         return  STATUS_INVALID_PARAMETER;
211      }
212
213    switch (BusConfigType)
214      {
215      case 1:
216         KeAcquireSpinLock(&PciLock, &oldIrql);
217         WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
218         WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value);
219         KeReleaseSpinLock(&PciLock, oldIrql);
220         return STATUS_SUCCESS;
221
222      case 2:
223         KeAcquireSpinLock(&PciLock, &oldIrql);
224         WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
225         WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
226         WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
227         WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
228         KeReleaseSpinLock(&PciLock, oldIrql);
229         return STATUS_SUCCESS;
230      }
231    return STATUS_UNSUCCESSFUL;
232 }
233
234
235 static NTSTATUS
236 WritePciConfigUlong(UCHAR Bus,
237                     UCHAR Slot,
238                     UCHAR Offset,
239                     ULONG Value)
240 {
241    KIRQL oldIrql;
242
243    if ((Offset & 3) != 0)
244      {
245         return  STATUS_INVALID_PARAMETER;
246      }
247
248    switch (BusConfigType)
249      {
250      case 1:
251         KeAcquireSpinLock(&PciLock, &oldIrql);
252         WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
253         WRITE_PORT_ULONG((PULONG)0xCFC, Value);
254         KeReleaseSpinLock(&PciLock, oldIrql);
255         return STATUS_SUCCESS;
256
257      case 2:
258         KeAcquireSpinLock(&PciLock, &oldIrql);
259         WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
260         WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
261         WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
262         WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
263         KeReleaseSpinLock(&PciLock, oldIrql);
264         return STATUS_SUCCESS;
265      }
266    return STATUS_UNSUCCESSFUL;
267 }
268
269
270 static ULONG STDCALL
271 HalpGetPciData(PBUS_HANDLER BusHandler,
272                ULONG BusNumber,
273                ULONG SlotNumber,
274                PVOID Buffer,
275                ULONG Offset,
276                ULONG Length)
277 {
278    PVOID Ptr = Buffer;
279    ULONG Address = Offset;
280    ULONG Len = Length;
281    ULONG Vendor;
282    UCHAR HeaderType;
283
284    DPRINT("HalpGetPciData() called.\n");
285    DPRINT("  BusNumber %lu\n", BusNumber);
286    DPRINT("  SlotNumber %lu\n", SlotNumber);
287    DPRINT("  Offset 0x%lx\n", Offset);
288    DPRINT("  Length 0x%lx\n", Length);
289
290    if ((Length == 0) || (BusConfigType == 0))
291      return 0;
292
293    ReadPciConfigUlong(BusNumber,
294                       SlotNumber & 0x1F,
295                       0x00,
296                       &Vendor);
297    /* some broken boards return 0 if a slot is empty: */
298    if (Vendor == 0xFFFFFFFF || Vendor == 0)
299    {
300      if (BusNumber == 0 && Offset == 0 && Length >= 2)
301      {
302         *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
303         return 2;
304      }
305      return 0;
306    }
307
308    /* 0E=PCI_HEADER_TYPE */
309    ReadPciConfigUchar(BusNumber,
310                       SlotNumber & 0x1F,
311                       0x0E,
312                       &HeaderType);
313    if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
314    {
315      if (Offset == 0 && Length >= 2)
316      {
317         *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
318         return 2;
319      }
320      return 0;
321    }
322    ReadPciConfigUlong(BusNumber,
323                       SlotNumber,
324                       0x00,
325                       &Vendor);
326    /* some broken boards return 0 if a slot is empty: */
327    if (Vendor == 0xFFFFFFFF || Vendor == 0)
328    {
329      if (BusNumber == 0 && Offset == 0 && Length >= 2)
330      {
331         *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
332         return 2;
333      }
334      return 0;
335    }
336
337    if ((Address & 1) && (Len >= 1))
338      {
339         ReadPciConfigUchar(BusNumber,
340                            SlotNumber,
341                            Address,
342                            Ptr);
343         Ptr = Ptr + 1;
344         Address++;
345         Len--;
346      }
347
348    if ((Address & 2) && (Len >= 2))
349      {
350         ReadPciConfigUshort(BusNumber,
351                             SlotNumber,
352                             Address,
353                             Ptr);
354         Ptr = Ptr + 2;
355         Address += 2;
356         Len -= 2;
357      }
358
359    while (Len >= 4)
360      {
361         ReadPciConfigUlong(BusNumber,
362                            SlotNumber,
363                            Address,
364                            Ptr);
365         Ptr = Ptr + 4;
366         Address += 4;
367         Len -= 4;
368      }
369
370    if (Len >= 2)
371      {
372         ReadPciConfigUshort(BusNumber,
373                             SlotNumber,
374                             Address,
375                             Ptr);
376         Ptr = Ptr + 2;
377         Address += 2;
378         Len -= 2;
379      }
380
381    if (Len >= 1)
382      {
383         ReadPciConfigUchar(BusNumber,
384                            SlotNumber,
385                            Address,
386                            Ptr);
387         Ptr = Ptr + 1;
388         Address++;
389         Len--;
390      }
391
392    return Length - Len;
393 }
394
395
396 static ULONG STDCALL
397 HalpSetPciData(PBUS_HANDLER BusHandler,
398                ULONG BusNumber,
399                ULONG SlotNumber,
400                PVOID Buffer,
401                ULONG Offset,
402                ULONG Length)
403 {
404    PVOID Ptr = Buffer;
405    ULONG Address = Offset;
406    ULONG Len = Length;
407    ULONG Vendor;
408    UCHAR HeaderType;
409
410    DPRINT("HalpSetPciData() called.\n");
411    DPRINT("  BusNumber %lu\n", BusNumber);
412    DPRINT("  SlotNumber %lu\n", SlotNumber);
413    DPRINT("  Offset 0x%lx\n", Offset);
414    DPRINT("  Length 0x%lx\n", Length);
415
416    if ((Length == 0) || (BusConfigType == 0))
417      return 0;
418
419    ReadPciConfigUlong(BusNumber,
420                       SlotNumber & 0x1F,
421                       0x00,
422                       &Vendor);
423    /* some broken boards return 0 if a slot is empty: */
424    if (Vendor == 0xFFFFFFFF || Vendor == 0)
425      return 0;
426
427
428    /* 0E=PCI_HEADER_TYPE */
429    ReadPciConfigUchar(BusNumber,
430                       SlotNumber & 0x1F,
431                       0x0E,
432                       &HeaderType);
433    if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
434      return 0;
435
436    ReadPciConfigUlong(BusNumber,
437                       SlotNumber,
438                       0x00,
439                       &Vendor);
440    /* some broken boards return 0 if a slot is empty: */
441    if (Vendor == 0xFFFFFFFF || Vendor == 0)
442      return 0;
443
444    if ((Address & 1) && (Len >= 1))
445      {
446         WritePciConfigUchar(BusNumber,
447                             SlotNumber,
448                             Address,
449                             *(PUCHAR)Ptr);
450         Ptr = Ptr + 1;
451         Address++;
452         Len--;
453      }
454
455    if ((Address & 2) && (Len >= 2))
456      {
457         WritePciConfigUshort(BusNumber,
458                              SlotNumber,
459                              Address,
460                              *(PUSHORT)Ptr);
461         Ptr = Ptr + 2;
462         Address += 2;
463         Len -= 2;
464      }
465
466    while (Len >= 4)
467      {
468         WritePciConfigUlong(BusNumber,
469                             SlotNumber,
470                             Address,
471                             *(PULONG)Ptr);
472         Ptr = Ptr + 4;
473         Address += 4;
474         Len -= 4;
475      }
476
477    if (Len >= 2)
478      {
479         WritePciConfigUshort(BusNumber,
480                              SlotNumber,
481                              Address,
482                              *(PUSHORT)Ptr);
483         Ptr = Ptr + 2;
484         Address += 2;
485         Len -= 2;
486      }
487
488    if (Len >= 1)
489      {
490         WritePciConfigUchar(BusNumber,
491                             SlotNumber,
492                             Address,
493                             *(PUCHAR)Ptr);
494         Ptr = Ptr + 1;
495         Address++;
496         Len--;
497      }
498
499    return Length - Len;
500 }
501
502
503 static ULONG
504 GetBusConfigType(VOID)
505 {
506    ULONG Value;
507    KIRQL oldIrql;
508
509    DPRINT("GetBusConfigType() called\n");
510
511    KeAcquireSpinLock(&PciLock, &oldIrql);
512  
513    DPRINT("Checking configuration type 1:");
514    WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
515    Value = READ_PORT_ULONG((PULONG)0xCF8);
516    WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
517    if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
518      {
519         WRITE_PORT_ULONG((PULONG)0xCF8, Value);
520         KeReleaseSpinLock(&PciLock, oldIrql);
521         DPRINT("  Success!\n");
522         return 1;
523      }
524    WRITE_PORT_ULONG((PULONG)0xCF8, Value);
525    DPRINT("  Unsuccessful!\n");
526
527    DPRINT("Checking configuration type 2:");
528    WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
529    WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
530    WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
531    if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
532        READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
533      {
534         KeReleaseSpinLock(&PciLock, oldIrql);
535         DPRINT("  Success!\n");
536         return 2;
537      }
538    KeReleaseSpinLock(&PciLock, oldIrql);
539    DPRINT("  Unsuccessful!\n");
540
541    DPRINT("No pci bus found!\n");
542    return 0;
543 }
544
545
546 static ULONG STDCALL
547 HalpGetPciInterruptVector(PVOID BusHandler,
548                           ULONG BusNumber,
549                           ULONG BusInterruptLevel,
550                           ULONG BusInterruptVector,
551                           PKIRQL Irql,
552                           PKAFFINITY Affinity)
553 {
554 #ifdef MP
555   *Irql = PROFILE_LEVEL - BusInterruptVector;
556   *Affinity = 0xFFFFFFFF;
557   return IRQ2VECTOR(BusInterruptVector);
558 #else
559   *Irql = PROFILE_LEVEL - BusInterruptVector;
560   *Affinity = 0xFFFFFFFF;
561   return BusInterruptVector;
562 #endif
563 }
564
565 static BOOLEAN STDCALL
566 HalpTranslatePciAddress(PBUS_HANDLER BusHandler,
567                         ULONG BusNumber,
568                         PHYSICAL_ADDRESS BusAddress,
569                         PULONG AddressSpace,
570                         PPHYSICAL_ADDRESS TranslatedAddress)
571 {
572    if (*AddressSpace == 0)
573      {
574         /* memory space */
575
576      }
577    else if (*AddressSpace == 1)
578      {
579         /* io space */
580
581      }
582    else
583      {
584         /* other */
585         return FALSE;
586      }
587
588    TranslatedAddress->QuadPart = BusAddress.QuadPart;
589
590    return TRUE;
591 }
592
593 /*
594  * Find the extent of a PCI decode..
595  */
596 static ULONG STDCALL
597 PciSize(ULONG Base, ULONG Mask)
598 {
599   ULONG Size = Mask & Base;   /* Find the significant bits */
600   Size = Size & ~(Size - 1);  /* Get the lowest of them to find the decode size */
601   return Size;
602 }
603
604 static NTSTATUS STDCALL
605 HalpAssignPciSlotResources(IN PBUS_HANDLER BusHandler,
606                            IN ULONG BusNumber,
607                            IN PUNICODE_STRING RegistryPath,
608                            IN PUNICODE_STRING DriverClassName,
609                            IN PDRIVER_OBJECT DriverObject,
610                            IN PDEVICE_OBJECT DeviceObject,
611                            IN ULONG SlotNumber,
612                            IN OUT PCM_RESOURCE_LIST *AllocatedResources)
613 {
614   UINT Address;
615   UINT NoAddresses;
616   ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];
617   ULONG Size[PCI_TYPE0_ADDRESSES];
618   NTSTATUS Status = STATUS_SUCCESS;
619   UCHAR Offset;
620   PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
621
622   /* FIXME: Should handle 64-bit addresses */
623
624   /* Read the PCI configuration space for the device and store base address and
625      size information in temporary storage. Count the number of valid base addresses */
626   NoAddresses = 0;
627   for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
628     {
629       Offset = offsetof(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]);
630       Status = ReadPciConfigUlong(BusNumber, SlotNumber,
631                                   Offset, BaseAddresses + Address);
632       if (! NT_SUCCESS(Status))
633         {
634           return Status;
635         }
636       if (0xffffffff == BaseAddresses[Address])
637         {
638           BaseAddresses[Address] = 0;
639         }
640       if (0 != BaseAddresses[Address])
641         {
642           NoAddresses++;
643           Status = WritePciConfigUlong(BusNumber, SlotNumber, Offset, 0xffffffff);
644           if (! NT_SUCCESS(Status))
645             {
646               WritePciConfigUlong(BusNumber, SlotNumber, Offset, BaseAddresses[Address]);
647               return Status;
648             }
649           Status = ReadPciConfigUlong(BusNumber, SlotNumber,
650                                       Offset, Size + Address);
651           if (! NT_SUCCESS(Status))
652             {
653               WritePciConfigUlong(BusNumber, SlotNumber, Offset, BaseAddresses[Address]);
654               return Status;
655             }
656           Status = WritePciConfigUlong(BusNumber, SlotNumber, Offset, BaseAddresses[Address]);
657           if (! NT_SUCCESS(Status))
658             {
659               return Status;
660             }
661
662         }
663     }
664
665   /* Allocate output buffer and initialize */
666   *AllocatedResources = ExAllocatePoolWithTag(PagedPool,
667                                               sizeof(CM_RESOURCE_LIST) +
668                                               (NoAddresses - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR),
669                                               TAG_PCI);
670   if (NULL == *AllocatedResources)
671     {
672     return STATUS_NO_MEMORY;
673     }
674   (*AllocatedResources)->Count = 1;
675   (*AllocatedResources)->List[0].InterfaceType = PCIBus;
676   (*AllocatedResources)->List[0].BusNumber = BusNumber;
677   (*AllocatedResources)->List[0].PartialResourceList.Version = 1;
678   (*AllocatedResources)->List[0].PartialResourceList.Revision = 1;
679   (*AllocatedResources)->List[0].PartialResourceList.Count = NoAddresses;
680   Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
681
682   /* Store configuration information */
683   for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
684     {
685       if (0 != BaseAddresses[Address])
686         {
687           if (PCI_BASE_ADDRESS_SPACE_MEMORY ==
688               (BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
689             {
690               Descriptor->Type = CmResourceTypeMemory;
691               Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
692               Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;             /* FIXME Just a guess */
693               Descriptor->u.Memory.Start.QuadPart = (BaseAddresses[Address] & PCI_BASE_ADDRESS_MEM_MASK);
694               Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_MEM_MASK);
695             }
696           else if (PCI_BASE_ADDRESS_SPACE_IO ==
697                    (BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
698             {
699               Descriptor->Type = CmResourceTypePort;
700               Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
701               Descriptor->Flags = CM_RESOURCE_PORT_IO;                       /* FIXME Just a guess */
702               Descriptor->u.Port.Start.QuadPart = BaseAddresses[Address] &= PCI_BASE_ADDRESS_IO_MASK;
703               Descriptor->u.Port.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_IO_MASK & 0xffff);
704             }
705           else
706             {
707               assert(FALSE);
708               return STATUS_UNSUCCESSFUL;
709             }
710           Descriptor++;
711         }
712     }
713
714   assert(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + NoAddresses);
715
716   /* FIXME: Should store the resources in the registry resource map */
717
718   return Status;
719 }
720
721
722 VOID
723 HalpInitPciBus(VOID)
724 {
725   PBUS_HANDLER BusHandler;
726
727   DPRINT("HalpInitPciBus() called.\n");
728
729   KeInitializeSpinLock (&PciLock);
730
731   BusConfigType = GetBusConfigType();
732   if (BusConfigType == 0)
733     return;
734
735   DPRINT("Bus configuration %lu used\n", BusConfigType);
736
737   /* pci bus (bus 0) handler */
738   BusHandler = HalpAllocateBusHandler(PCIBus,
739                                       PCIConfiguration,
740                                       0);
741   BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
742   BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
743   BusHandler->GetInterruptVector =
744     (pGetInterruptVector)HalpGetPciInterruptVector;
745   BusHandler->TranslateBusAddress = 
746     (pTranslateBusAddress)HalpTranslatePciAddress;
747 //      BusHandler->AdjustResourceList =
748 //              (pGetSetBusData)HalpAdjustPciResourceList;
749   BusHandler->AssignSlotResources =
750     (pAssignSlotResources)HalpAssignPciSlotResources;
751
752
753   /* agp bus (bus 1) handler */
754   BusHandler = HalpAllocateBusHandler(PCIBus,
755                                       PCIConfiguration,
756                                       1);
757   BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
758   BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
759   BusHandler->GetInterruptVector =
760     (pGetInterruptVector)HalpGetPciInterruptVector;
761   BusHandler->TranslateBusAddress = 
762     (pTranslateBusAddress)HalpTranslatePciAddress;
763 //      BusHandler->AdjustResourceList =
764 //              (pGetSetBusData)HalpAdjustPciResourceList;
765   BusHandler->AssignSlotResources =
766     (pAssignSlotResources)HalpAssignPciSlotResources;
767
768   DPRINT("HalpInitPciBus() finished.\n");
769 }
770
771 /* EOF */