Applied patch set 6 by Ben, derived from Anthony's megapatch, and minor
[pintos-anon] / src / devices / pci.c
1 #define PCI_TRANSLATION_ENABLE 1
2
3 #include "devices/pci.h"
4 #include "threads/malloc.h"
5 #include "threads/interrupt.h"
6 #include "threads/pte.h"
7 #include "threads/io.h"
8 #include "pci_lookup.h"
9 #include <round.h>
10 #include <list.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include <stdio.h>
14
15 extern uint32_t *base_page_dir;
16
17 #define PCI_REG_ADDR    0xcf8
18 #define PCI_REG_DATA    0xcfc
19 #define pci_config_offset(bus, dev, func, reg)  (0x80000000 | ((bus) << 16) | ((dev) << 11) | ((func) << 8) | (reg & (~3)))
20
21 #define PCI_MAX_DEV_PER_BUS     32
22 #define PCI_MAX_FUNC_PER_DEV    8
23
24 #define PCI_HEADER_SZ           256
25
26 #define PCI_CMD_IO              0x001   /* enable io response */
27 #define PCI_CMD_MEMORY          0x002   /* enable memory response */
28 #define PCI_CMD_MASTER          0x004   /* enable bus mastering */
29 #define PCI_CMD_SPECIAL         0x008   /* enable special cycles */
30 #define PCI_CMD_INVALIDATE      0x010   /* memory write + invalidate */
31 #define PCI_CMD_PALETTE         0x020   /* palette snooping */
32 #define PCI_CMD_PARITY          0x040   /* parity checking */
33 #define PCI_CMD_WAIT            0x080   /* address/data stepping */
34 #define PCI_CMD_SERR            0x100   /* serr */
35 #define PCI_CMD_FASTBACK        0x200   /* back-to-back writing */
36 #define PCI_CMD_INTX_DISABLE    0x400   /* emulation disable */
37
38 #define PCI_STATUS_CAPLIST      0x10    /* capability list */
39 #define PCI_STATUS_66MHZ        0x20    /* 66mhz pci 2.1 bus */
40 #define PCI_STATUS_UDF          0x40    /* user definable features */
41 #define PCI_STATUS_FASTBACK     0x80    /* fast back to back */
42 #define PCI_STATUS_PARITY       0x100   /* parity error detected */
43 #define PCI_STATUS_DEVSEL       0x600   /* devsel mask */
44 #define PCI_STATUS_DEVSEL_FAST  0
45 #define PCI_STATUS_DEVSEL_MED   0x200
46 #define PCI_STATUS_DEVSEL_SLOW  0x400
47 #define PCI_STATUS_SIG_ABORT    0x0800  /* set on target abort */
48 #define PCI_STATUS_REC_ABORT    0x1000  /* master ack of abort */
49 #define PCI_STATUS_REC_ABORT_M  0x2000  /* set on master abort */
50 #define PCI_STATUS_SERR         0x4000  /* system error */
51 #define PCI_STATUS_PARITY2      0x8000  /* set on parity err */
52
53 #define PCI_HEADER_NORMAL       0
54 #define PCI_HEADER_BRIDGE       1
55 #define PCI_HEADER_CARDBUS      2
56
57 #define PCI_HEADER_MASK         0x7f
58 #define PCI_HEADER_MULTIFUNC    0x80
59
60 #define pci_get_reg_offset(x)   (&(((pci_config_header*)(NULL))->x))
61
62 #define PCI_VENDOR_INVALID      0xffff
63
64 #define PCI_BASEADDR_IO         0x00000001
65 #define PCI_BASEADDR_TYPEMASK   0x00000006
66 #define PCI_BASEADDR_32BIT      0x00000000
67 #define PCI_BASEADDR_64BIT      0x00000004
68 #define PCI_BASEADDR_PREFETCH   0x00000008
69 #define PCI_BASEADDR_ADDR32     0xfffffff0
70 #define PCI_BASEADDR_ADDR64     0xfffffffffffffff0
71 #define PCI_BASEADDR_IOPORT     0xfffffffc
72
73 #pragma pack(1)
74
75 struct pci_config_header
76 {
77   uint16_t pci_vendor_id;
78   uint16_t pci_device_id;
79
80   uint16_t pci_command;
81   uint16_t pci_status;
82
83   uint8_t pci_revision;
84
85   /* pci class */
86   uint8_t pci_interface;
87   uint8_t pci_minor;
88   uint8_t pci_major;
89
90   uint8_t pci_cachelinesz;
91   uint8_t pci_latency;
92   uint8_t pci_header;           /* header type */
93   uint8_t pci_bist;             /* self test */
94
95   uint32_t pci_base_reg[6];
96   uint32_t pci_cis;             /* cardbus cis pointer */
97   uint16_t pci_sub_vendor_id;
98   uint16_t pci_sub_id;
99   uint32_t pci_rom_addr;
100   uint8_t pci_capabilities;
101   uint8_t pci_resv[7];
102   uint8_t pci_int_line;
103   uint8_t pci_int_pin;
104   uint8_t pci_min_gnt;
105   uint8_t pci_max_latency;
106 };
107
108 #pragma pack()
109
110 #define PCI_BASE_COUNT          6
111 struct pci_dev
112 {
113   struct pci_config_header pch;
114   uint8_t bus, dev, func;
115   int base_reg_size[PCI_BASE_COUNT];
116
117   pci_handler_func *irq_handler;
118   void *irq_handler_aux;
119
120   struct list io_ranges;
121   struct list_elem peer;
122   struct list_elem int_peer;
123 };
124
125 enum pci_io_type
126 { PCI_IO_MEM, PCI_IO_PORT };
127
128 /* represents a PCI IO range */
129 struct pci_io
130 {
131   struct pci_dev *dev;
132   enum pci_io_type type;
133   size_t size;  /* bytes in range */
134   union
135   {
136     void *ptr;  /* virtual memory address */
137     int port;   /* io port */
138   } addr;
139   struct list_elem peer; /* linkage */
140 };
141
142
143 static void pci_write_config (int bus, int dev, int func, int reg,
144                               int size, uint32_t data);
145 static uint32_t pci_read_config (int bus, int dev, int func, int reg,
146                                  int size);
147 static void pci_read_all_config (int bus, int dev, int func,
148                                  struct pci_config_header *pch);
149 static int pci_scan_bus (int bus);
150 static int pci_probe (int bus, int dev, int func,
151                       struct pci_config_header *ph);
152 static int pci_pci_bridge (struct pci_dev *pd);
153 static void pci_power_on (struct pci_dev *pd);
154 static void pci_setup_io (struct pci_dev *pd);
155 static void pci_interrupt (struct intr_frame *);
156 static void pci_print_dev_info (struct pci_dev *pd);
157 static void *pci_alloc_mem (void *phys_ptr, int pages);
158
159 static struct list devices;
160 static struct list int_devices;
161
162 /* number of pages that have been allocated to pci devices in the pci zone */
163 static int num_pci_pages;
164
165 void
166 pci_init (void)
167 {
168   list_init (&devices);
169   list_init (&int_devices);
170
171   num_pci_pages = 0;
172
173   pci_scan_bus (0);
174   pci_print_stats ();
175 }
176
177 struct pci_dev *
178 pci_get_device (int vendor, int device, int func, int n)
179 {
180   struct list_elem *e;
181   int count;
182
183   count = 0;
184   e = list_begin (&devices);
185   while (e != list_end (&devices))
186     {
187       struct pci_dev *pd;
188
189       pd = list_entry (e, struct pci_dev, peer);
190       if (pd->pch.pci_vendor_id == vendor && pd->pch.pci_device_id == device)
191         if (pd->func == func)
192           {
193             if (count == n)
194               return pd;
195             count++;
196           }
197
198       e = list_next (e);
199     }
200
201   return NULL;
202 }
203
204 struct pci_dev *
205 pci_get_dev_by_class (int major, int minor, int iface, int n)
206 {
207   struct list_elem *e;
208   int count;
209
210   count = 0;
211   e = list_begin (&devices);
212   while (e != list_end (&devices))
213     {
214       struct pci_dev *pd;
215
216       pd = list_entry (e, struct pci_dev, peer);
217       if (pd->pch.pci_major == major && pd->pch.pci_minor == minor &&
218           pd->pch.pci_interface == iface)
219         {
220           if (count == n)
221             return pd;
222           count++;
223         }
224
225       e = list_next (e);
226     }
227
228   return NULL;
229
230 }
231
232 struct pci_io *
233 pci_io_enum (struct pci_dev *pio, struct pci_io *last)
234 {
235   struct list_elem *e;
236
237   if (last != NULL)
238     e = list_next (&last->peer);
239   else
240     e = list_begin (&pio->io_ranges);
241
242   if (e == list_end (&pio->io_ranges))
243     return NULL;
244
245   return list_entry (e, struct pci_io, peer);
246 }
247
248 void
249 pci_register_irq (struct pci_dev *pd, pci_handler_func * f, void *aux)
250 {
251   int int_vec;
252   ASSERT (pd != NULL);
253   ASSERT (pd->irq_handler == NULL);
254
255   pd->irq_handler_aux = aux;
256   pd->irq_handler = f;
257   int_vec = pd->pch.pci_int_line + 0x20;
258
259   list_push_back (&int_devices, &pd->int_peer);
260
261   /* ensure that pci interrupt is hooked */
262   if (!intr_is_registered (int_vec))
263     intr_register_ext (int_vec, pci_interrupt, "PCI");
264 }
265
266 void
267 pci_unregister_irq (struct pci_dev *pd)
268 {
269   ASSERT (pd != NULL);
270
271   intr_disable ();
272   list_remove (&pd->int_peer);
273   intr_enable ();
274
275   pd->irq_handler = NULL;
276   pd->irq_handler_aux = NULL;
277 }
278
279 size_t
280 pci_io_size (struct pci_io *pio)
281 {
282   ASSERT (pio != NULL);
283
284   return pio->size;
285 }
286
287 void
288 pci_reg_write32 (struct pci_io *pio, int reg, uint32_t data)
289 {
290   ASSERT (pio != NULL);
291   ASSERT ((unsigned) reg < pio->size);
292
293   if (pio->type == PCI_IO_MEM)
294     {
295       *((uint32_t *) (pio->addr.ptr + reg)) = data;
296     }
297   else if (pio->type == PCI_IO_PORT)
298     {
299       outl (pio->addr.port + reg, data);
300     }
301   else
302     PANIC ("pci: Invalid IO type\n");
303 }
304
305 void
306 pci_reg_write16 (struct pci_io *pio, int reg, uint16_t data)
307 {
308   ASSERT (pio != NULL);
309   ASSERT ((unsigned) reg < pio->size);
310
311   if (pio->type == PCI_IO_MEM)
312     {
313       *((uint16_t *) (pio->addr.ptr + reg)) = data;
314     }
315   else if (pio->type == PCI_IO_PORT)
316     {
317       outw (pio->addr.port + reg, data);
318     }
319   else
320     PANIC ("pci: Invalid IO type\n");
321 }
322
323 void
324 pci_reg_write8 (struct pci_io *pio, int reg, uint8_t data)
325 {
326   ASSERT (pio != NULL);
327   ASSERT ((unsigned) reg < pio->size);
328
329   if (pio->type == PCI_IO_MEM)
330     {
331       *((uint8_t *) (pio->addr.ptr + reg)) = data;
332     }
333   else if (pio->type == PCI_IO_PORT)
334     {
335       outb (pio->addr.port + reg, data);
336     }
337   else
338     PANIC ("pci: Invalid IO type\n");
339 }
340
341 uint32_t
342 pci_reg_read32 (struct pci_io *pio, int reg)
343 {
344   uint32_t ret;
345
346   ASSERT (pio != NULL);
347   ASSERT ((unsigned) reg < pio->size);
348
349   if (pio->type == PCI_IO_MEM)
350     {
351       ret = *((uint32_t *) (pio->addr.ptr + reg));
352     }
353   else if (pio->type == PCI_IO_PORT)
354     {
355       ret = inl (pio->addr.port + reg);
356     }
357   else
358     PANIC ("pci: Invalid IO type\n");
359
360   return ret;
361 }
362
363 uint16_t
364 pci_reg_read16 (struct pci_io * pio, int reg)
365 {
366   uint16_t ret;
367
368   ASSERT (pio != NULL);
369   ASSERT ((unsigned) reg < pio->size);
370
371   ret = 0;
372   if (pio->type == PCI_IO_MEM)
373     {
374       ret = *((uint16_t *) (pio->addr.ptr + reg));
375     }
376   else if (pio->type == PCI_IO_PORT)
377     {
378       ret = inw (pio->addr.port + reg);
379     }
380   else
381     PANIC ("pci: Invalid IO type\n");
382
383   return ret;
384
385 }
386
387 uint8_t
388 pci_reg_read8 (struct pci_io * pio, int reg)
389 {
390   uint8_t ret;
391
392   ASSERT (pio != NULL);
393   ASSERT ((unsigned) reg < pio->size);
394
395   if (pio->type == PCI_IO_MEM)
396     {
397       ret = *((uint8_t *) (pio->addr.ptr + reg));
398     }
399   else if (pio->type == PCI_IO_PORT)
400     {
401       ret = inb (pio->addr.port + reg);
402     }
403   else
404     PANIC ("pci: Invalid IO type\n");
405
406   return ret;
407 }
408
409 void
410 pci_read_in (struct pci_io *pio UNUSED, int off UNUSED, size_t size UNUSED,
411              void *buf UNUSED)
412 {
413   PANIC ("pci_read_in: STUB");
414 }
415
416 void
417 pci_write_out (struct pci_io *pio UNUSED, int off UNUSED, size_t size UNUSED,
418                const void *buf UNUSED)
419 {
420   PANIC ("pci_write_out: STUB");
421 }
422
423 static void
424 pci_write_config (int bus, int dev, int func, int reg,
425                   int size, uint32_t data)
426 {
427   int config_offset;
428
429   config_offset = pci_config_offset (bus, dev, func, reg);
430
431   outl (PCI_REG_ADDR, config_offset);
432
433   switch (size)
434     {
435     case 1:
436       outb (PCI_REG_DATA + (reg & 3), data);
437       break;
438
439     case 2:
440       outw (PCI_REG_DATA + (reg & 3), data);
441       break;
442
443     case 4:
444       outl (PCI_REG_DATA, data);
445       break;
446     }
447 }
448
449 static uint32_t
450 pci_read_config (int bus, int dev, int func, int reg, int size)
451 {
452   uint32_t ret;
453   int config_offset;
454
455   config_offset = pci_config_offset (bus, dev, func, reg);
456
457   outl (PCI_REG_ADDR, config_offset);
458
459   switch (size)
460     {
461     case 1:
462       ret = inb (PCI_REG_DATA);
463       break;
464     case 2:
465       ret = inw (PCI_REG_DATA);
466       break;
467     case 4:
468       ret = inl (PCI_REG_DATA);
469       break;
470     default:
471       PANIC ("pci: Strange config read size\n");
472     }
473
474   return ret;
475 }
476
477 /* read entire configuration header into memory */
478 static void
479 pci_read_all_config (int bus, int dev, int func,
480                      struct pci_config_header *pch)
481 {
482   unsigned int i;
483   for (i = 0; i < ((sizeof (struct pci_config_header) + 3) & ~3) / 4; i++)
484     {
485       ((uint32_t *) pch)[i] = pci_read_config (bus, dev, func, i * 4, 4);
486     }
487 }
488
489
490 /** scan PCI bus for all devices */
491 static int
492 pci_scan_bus (int bus)
493 {
494   int dev;
495   int max_bus;
496
497   max_bus = 0;
498
499   for (dev = 0; dev < PCI_MAX_DEV_PER_BUS; dev++)
500     {
501       struct pci_config_header pch;
502       int func_cnt, func;
503
504       pci_read_all_config (bus, dev, 0, &pch);
505
506       if (pch.pci_vendor_id == PCI_VENDOR_INVALID)
507         continue;
508
509       func_cnt = 8;
510       if (!(pch.pci_header & PCI_HEADER_MULTIFUNC))
511         {
512           func_cnt = 1;
513         }
514
515       for (func = 0; func < func_cnt; func++)
516         {
517           int retbus;
518           retbus = pci_probe (bus, dev, func, &pch);
519           if (retbus > max_bus)
520             max_bus = retbus;
521         }
522     }
523
524   return max_bus;
525 }
526
527 /* get all information for a PCI device given bus/dev/func 
528    add pci device to device list if applicable 
529    return a new bus number if new bus is found
530  */
531 static int
532 pci_probe (int bus, int dev, int func, struct pci_config_header *ph)
533 {
534   struct pci_dev *pd;
535
536   if (func != 0)
537     {
538       pci_read_all_config (bus, dev, func, ph);
539       if (ph->pci_vendor_id == PCI_VENDOR_INVALID)
540         return bus;
541     }
542
543   pd = malloc (sizeof (struct pci_dev));
544   memcpy (&pd->pch, ph, sizeof (struct pci_config_header));
545   pd->irq_handler = NULL;
546   pd->irq_handler_aux = NULL;
547   pd->bus = bus;
548   pd->dev = dev;
549   pd->func = func;
550
551   list_init (&pd->io_ranges);
552   list_push_back (&devices, &pd->peer);
553
554
555   if (ph->pci_major == PCI_MAJOR_BRIDGE)
556     {
557       if (ph->pci_minor == PCI_MINOR_PCI)
558         return pci_pci_bridge (pd);
559     }
560
561   pci_setup_io (pd);
562   pci_power_on (pd);
563
564   return bus;
565 }
566
567 static void
568 pci_setup_io (struct pci_dev *pd)
569 {
570   int i;
571   for (i = 0; i < PCI_BASE_COUNT; i++)
572     {
573       uint32_t tmp;
574       struct pci_io *pio;
575
576       if (pd->pch.pci_base_reg[i] == 0)
577         {
578           continue;
579         }
580
581       /* determine io granularity.. */
582       pci_write_config (pd->bus, pd->dev, pd->func,
583                         offsetof (struct pci_config_header, pci_base_reg[i]),
584                         4, ~0);
585
586       tmp =
587         pci_read_config (pd->bus, pd->dev, pd->func,
588                          offsetof (struct pci_config_header, pci_base_reg[i]),
589                          4);
590
591       /* configure BAR to the default */
592       pci_write_config (pd->bus, pd->dev, pd->func,
593                         offsetof (struct pci_config_header, pci_base_reg[i]),
594                         4, pd->pch.pci_base_reg[i]);
595
596       pio = malloc (sizeof (struct pci_io));
597       pio->dev = pd;
598
599       if (tmp & PCI_BASEADDR_IO)
600         {
601           pio->type = PCI_IO_PORT;
602           pio->size = (uint16_t) ((~tmp + 1) & 0xffff) + 1;
603           pio->addr.port = pd->pch.pci_base_reg[i] & ~1;
604         }
605       else
606         {
607           uint32_t ofs;
608
609           pio->type = PCI_IO_MEM;
610           pio->size = ROUND_UP ((~tmp + 1), PGSIZE);
611           ofs = (pd->pch.pci_base_reg[i] & 0xfffffff0 & PGMASK);
612           pio->addr.ptr = pci_alloc_mem ((void *) pd->pch.pci_base_reg[i],
613                                          pio->size / PGSIZE);
614           if (pio->addr.ptr == NULL)
615             {
616               printf ("PCI: %d pages for %d:%d.%d failed - may not work\n",
617                       pio->size / PGSIZE, pd->bus, pd->dev, pd->func);
618               free (pio);
619               pio = NULL;
620             }
621           else
622             {
623               pio->addr.ptr = (void *) ((uintptr_t) pio->addr.ptr + ofs);
624             }
625         }
626
627       /* add IO struct to device, if valid */
628       if (pio != NULL)
629         list_push_back (&pd->io_ranges, &pio->peer);
630     }
631
632 }
633
634 static void
635 pci_power_on (struct pci_dev *pd UNUSED)
636 {
637   /* STUB */
638 }
639
640 static int
641 pci_pci_bridge (struct pci_dev *pd)
642 {
643   int max_bus;
644   uint16_t command;
645
646   /* put bus into offline mode */
647   command = pd->pch.pci_command;
648   command &= ~0x3;
649   pci_write_config (pd->bus, pd->dev, pd->func,
650                     offsetof (struct pci_config_header, pci_command),
651                     2, command);
652   pd->pch.pci_command = command;
653
654   /* set up primary bus */
655   pci_write_config (pd->bus, pd->dev, pd->func, 0x18, 1, pd->bus);
656   /* secondary bus */
657   pci_write_config (pd->bus, pd->dev, pd->func, 0x19, 1, pd->bus + 1);
658
659   /* disable subordinates */
660   pci_write_config (pd->bus, pd->dev, pd->func, 0x1a, 1, 0xff);
661
662   /* scan this new bus */
663   max_bus = pci_scan_bus (pd->bus + 1);
664
665   /* set subordinate to the actual last bus */
666   pci_write_config (pd->bus, pd->dev, pd->func, 0x1a, 1, max_bus);
667
668   /* put online */
669   command |= 0x03;
670   pci_write_config (pd->bus, pd->dev, pd->func,
671                     offsetof (struct pci_config_header, pci_command),
672                     2, command);
673   pd->pch.pci_command = command;
674
675   return max_bus;
676 }
677
678 /* alert all PCI devices waiting on interrupt line that IRQ fired */
679 static void
680 pci_interrupt (struct intr_frame *frame)
681 {
682   struct list_elem *e;
683   int int_line;
684
685   int_line = frame->vec_no - 0x20;
686   e = list_begin (&int_devices);
687   while (e != list_end (&int_devices))
688     {
689       struct pci_dev *pd;
690
691       pd = list_entry (e, struct pci_dev, int_peer);
692       if (pd->pch.pci_int_line == int_line)
693         pd->irq_handler (pd->irq_handler_aux);
694       e = list_next (e);
695     }
696 }
697
698 /* display information on all USB devices */
699 void
700 pci_print_stats (void)
701 {
702   struct list_elem *e;
703
704   e = list_begin (&devices);
705   while (e != list_end (&devices))
706     {
707       struct pci_dev *pd;
708
709       pd = list_entry (e, struct pci_dev, peer);
710       pci_print_dev_info (pd);
711
712       e = list_next (e);
713     }
714 }
715
716 static void
717 pci_print_dev_info (struct pci_dev *pd)
718 {
719   printf ("PCI Device %d:%d.%d (%x,%x): %s - %s (%s) IRQ %d\n",
720           pd->bus, pd->dev, pd->func,
721           pd->pch.pci_vendor_id,
722           pd->pch.pci_device_id,
723           pci_lookup_vendor (pd->pch.pci_vendor_id),
724           pci_lookup_device (pd->pch.pci_vendor_id, pd->pch.pci_device_id),
725           pci_lookup_class (pd->pch.pci_major, pd->pch.pci_minor,
726                             pd->pch.pci_interface), pd->pch.pci_int_line);
727 }
728
729 void
730 pci_mask_irq (struct pci_dev *pd)
731 {
732   intr_irq_mask (pd->pch.pci_int_line);
733 }
734
735 void
736 pci_unmask_irq (struct pci_dev *pd)
737 {
738   intr_irq_unmask (pd->pch.pci_int_line);
739 }
740
741 void
742 pci_write_config16 (struct pci_dev *pd, int off, uint16_t data)
743 {
744   pci_write_config (pd->bus, pd->dev, pd->func, off, 2, data);
745 }
746
747 void
748 pci_write_config32 (struct pci_dev *pd, int off, uint32_t data)
749 {
750   pci_write_config (pd->bus, pd->dev, pd->func, off, 4, data);
751 }
752
753 void
754 pci_write_config8 (struct pci_dev *pd, int off, uint8_t data)
755 {
756   pci_write_config (pd->bus, pd->dev, pd->func, off, 1, data);
757 }
758
759 uint8_t
760 pci_read_config8 (struct pci_dev *pd, int off)
761 {
762   return pci_read_config (pd->bus, pd->dev, pd->func, off, 1);
763 }
764
765 uint16_t
766 pci_read_config16 (struct pci_dev * pd, int off)
767 {
768   return pci_read_config (pd->bus, pd->dev, pd->func, off, 2);
769 }
770
771 uint32_t
772 pci_read_config32 (struct pci_dev * pd, int off)
773 {
774   return pci_read_config (pd->bus, pd->dev, pd->func, off, 4);
775 }
776
777
778 /** allocate PCI memory pages for PCI devices */
779 static void *
780 pci_alloc_mem (void *phys_ptr, int pages)
781 {
782   void *vaddr;
783   int i;
784
785   phys_ptr = (void *) ((uintptr_t) phys_ptr & ~PGMASK);
786
787   /* not enough space to allocate? */
788   if ((unsigned) (num_pci_pages + pages) >= (unsigned) PCI_ADDR_ZONE_PAGES)
789     {
790       return NULL;
791     }
792
793   /* insert into PCI_ZONE */
794   for (i = 0; i < pages; i++)
795     {
796       uint32_t pte_idx = (num_pci_pages + i) % 1024;
797       uint32_t pde_idx = (num_pci_pages + i) / 1024;
798       uint32_t *pt;
799       uint32_t pte;
800
801       pde_idx += pd_no ((void *) PCI_ADDR_ZONE_BEGIN);
802       pte = ((uint32_t) phys_ptr + (i * PGSIZE)) | PTE_P | PTE_W | PTE_CD;
803       pt = (uint32_t *) (ptov (base_page_dir[pde_idx] & ~PGMASK));
804       pt[pte_idx] = pte;
805     }
806
807   vaddr = (void *) (PCI_ADDR_ZONE_BEGIN + (num_pci_pages * PGSIZE));
808   num_pci_pages += pages;
809
810   return vaddr;
811 }