00001 #define PCI_TRANSLATION_ENABLE 1
00002
00003
00004 #include "devices/pci.h"
00005 #include "threads/malloc.h"
00006 #include "threads/interrupt.h"
00007 #include "threads/pte.h"
00008 #include "threads/io.h"
00009 #include "pci_lookup.h"
00010 #include <round.h>
00011 #include <list.h>
00012 #include <stdint.h>
00013 #include <string.h>
00014 #include <stdio.h>
00015
00016 extern uint32_t *base_page_dir;
00017
00018 #define PCI_REG_ADDR 0xcf8
00019 #define PCI_REG_DATA 0xcfc
00020 #define pci_config_offset(bus, dev, func, reg) (0x80000000 | ((bus) << 16) | ((dev) << 11) | ((func) << 8) | (reg & (~3)))
00021
00022 #define PCI_MAX_DEV_PER_BUS 32
00023 #define PCI_MAX_FUNC_PER_DEV 8
00024
00025 #define PCI_HEADER_SZ 256
00026
00027 #define PCI_CMD_IO 0x001
00028 #define PCI_CMD_MEMORY 0x002
00029 #define PCI_CMD_MASTER 0x004
00030 #define PCI_CMD_SPECIAL 0x008
00031 #define PCI_CMD_INVALIDATE 0x010
00032 #define PCI_CMD_PALETTE 0x020
00033 #define PCI_CMD_PARITY 0x040
00034 #define PCI_CMD_WAIT 0x080
00035 #define PCI_CMD_SERR 0x100
00036 #define PCI_CMD_FASTBACK 0x200
00037 #define PCI_CMD_INTX_DISABLE 0x400
00038
00039 #define PCI_STATUS_CAPLIST 0x10
00040 #define PCI_STATUS_66MHZ 0x20
00041 #define PCI_STATUS_UDF 0x40
00042 #define PCI_STATUS_FASTBACK 0x80
00043 #define PCI_STATUS_PARITY 0x100
00044 #define PCI_STATUS_DEVSEL 0x600
00045 #define PCI_STATUS_DEVSEL_FAST 0
00046 #define PCI_STATUS_DEVSEL_MED 0x200
00047 #define PCI_STATUS_DEVSEL_SLOW 0x400
00048 #define PCI_STATUS_SIG_ABORT 0x0800
00049 #define PCI_STATUS_REC_ABORT 0x1000
00050 #define PCI_STATUS_REC_ABORT_M 0x2000
00051 #define PCI_STATUS_SERR 0x4000
00052 #define PCI_STATUS_PARITY2 0x8000
00053
00054 #define PCI_HEADER_NORMAL 0
00055 #define PCI_HEADER_BRIDGE 1
00056 #define PCI_HEADER_CARDBUS 2
00057
00058 #define PCI_HEADER_MASK 0x7f
00059 #define PCI_HEADER_MULTIFUNC 0x80
00060
00061 #define pci_get_reg_offset(x) (&(((pci_config_header*)(NULL))->x))
00062
00063 #define PCI_VENDOR_INVALID 0xffff
00064
00065 #define PCI_BASEADDR_IO 0x00000001
00066 #define PCI_BASEADDR_TYPEMASK 0x00000006
00067 #define PCI_BASEADDR_32BIT 0x00000000
00068 #define PCI_BASEADDR_64BIT 0x00000004
00069 #define PCI_BASEADDR_PREFETCH 0x00000008
00070 #define PCI_BASEADDR_ADDR32 0xfffffff0
00071 #define PCI_BASEADDR_ADDR64 0xfffffffffffffff0
00072 #define PCI_BASEADDR_IOPORT 0xfffffffc
00073
00074 #pragma pack(1)
00075
00076 struct pci_config_header
00077 {
00078 uint16_t pci_vendor_id;
00079 uint16_t pci_device_id;
00080
00081 uint16_t pci_command;
00082 uint16_t pci_status;
00083
00084 uint8_t pci_revision;
00085
00086
00087 uint8_t pci_interface;
00088 uint8_t pci_minor;
00089 uint8_t pci_major;
00090
00091 uint8_t pci_cachelinesz;
00092 uint8_t pci_latency;
00093 uint8_t pci_header;
00094 uint8_t pci_bist;
00095
00096 uint32_t pci_base_reg[6];
00097 uint32_t pci_cis;
00098 uint16_t pci_sub_vendor_id;
00099 uint16_t pci_sub_id;
00100 uint32_t pci_rom_addr;
00101 uint8_t pci_capabilities;
00102 uint8_t pci_resv[7];
00103 uint8_t pci_int_line;
00104 uint8_t pci_int_pin;
00105 uint8_t pci_min_gnt;
00106 uint8_t pci_max_latency;
00107 };
00108
00109 #pragma pack()
00110
00111 #define PCI_BASE_COUNT 6
00112 struct pci_dev
00113 {
00114 struct pci_config_header pch;
00115 uint8_t bus, dev, func;
00116 int base_reg_size[PCI_BASE_COUNT];
00117
00118 pci_handler_func *irq_handler;
00119 void *irq_handler_aux;
00120
00121 struct list io_ranges;
00122 struct list_elem peer;
00123 struct list_elem int_peer;
00124 };
00125
00126 enum pci_io_type
00127 { PCI_IO_MEM, PCI_IO_PORT };
00128
00129
00130 struct pci_io
00131 {
00132 struct pci_dev *dev;
00133 enum pci_io_type type;
00134 size_t size;
00135 union
00136 {
00137 void *ptr;
00138 int port;
00139 } addr;
00140 struct list_elem peer;
00141 };
00142
00143
00144 static void pci_write_config (int bus, int dev, int func, int reg,
00145 int size, uint32_t data);
00146 static uint32_t pci_read_config (int bus, int dev, int func, int reg,
00147 int size);
00148 static void pci_read_all_config (int bus, int dev, int func,
00149 struct pci_config_header *pch);
00150 static int pci_scan_bus (int bus);
00151 static int pci_probe (int bus, int dev, int func,
00152 struct pci_config_header *ph);
00153 static int pci_pci_bridge (struct pci_dev *pd);
00154 static void pci_power_on (struct pci_dev *pd);
00155 static void pci_setup_io (struct pci_dev *pd);
00156 static void pci_interrupt (struct intr_frame *);
00157 static void pci_print_dev_info (struct pci_dev *pd);
00158 static void *pci_alloc_mem (void *phys_ptr, int pages);
00159
00160 static struct list devices;
00161 static struct list int_devices;
00162
00163
00164 static int num_pci_pages;
00165
00166 void
00167 pci_init (void)
00168 {
00169 list_init (&devices);
00170 list_init (&int_devices);
00171
00172 num_pci_pages = 0;
00173
00174 pci_scan_bus (0);
00175 pci_print_stats ();
00176 }
00177
00178 struct pci_dev *
00179 pci_get_device (int vendor, int device, int func, int n)
00180 {
00181 struct list_elem *e;
00182 int count;
00183
00184 count = 0;
00185 e = list_begin (&devices);
00186 while (e != list_end (&devices))
00187 {
00188 struct pci_dev *pd;
00189
00190 pd = list_entry (e, struct pci_dev, peer);
00191 if (pd->pch.pci_vendor_id == vendor && pd->pch.pci_device_id == device)
00192 if (pd->func == func)
00193 {
00194 if (count == n)
00195 return pd;
00196 count++;
00197 }
00198
00199 e = list_next (e);
00200 }
00201
00202 return NULL;
00203 }
00204
00205 struct pci_dev *
00206 pci_get_dev_by_class (int major, int minor, int iface, int n)
00207 {
00208 struct list_elem *e;
00209 int count;
00210
00211 count = 0;
00212 e = list_begin (&devices);
00213 while (e != list_end (&devices))
00214 {
00215 struct pci_dev *pd;
00216
00217 pd = list_entry (e, struct pci_dev, peer);
00218 if (pd->pch.pci_major == major && pd->pch.pci_minor == minor &&
00219 pd->pch.pci_interface == iface)
00220 {
00221 if (count == n)
00222 return pd;
00223 count++;
00224 }
00225
00226 e = list_next (e);
00227 }
00228
00229 return NULL;
00230
00231 }
00232
00233 struct pci_io *
00234 pci_io_enum (struct pci_dev *pio, struct pci_io *last)
00235 {
00236 struct list_elem *e;
00237
00238 if (last != NULL)
00239 e = list_next (&last->peer);
00240 else
00241 e = list_begin (&pio->io_ranges);
00242
00243 if (e == list_end (&pio->io_ranges))
00244 return NULL;
00245
00246 return list_entry (e, struct pci_io, peer);
00247 }
00248
00249 void
00250 pci_register_irq (struct pci_dev *pd, pci_handler_func * f, void *aux)
00251 {
00252 int int_vec;
00253 ASSERT (pd != NULL);
00254 ASSERT (pd->irq_handler == NULL);
00255
00256 pd->irq_handler_aux = aux;
00257 pd->irq_handler = f;
00258 int_vec = pd->pch.pci_int_line + 0x20;
00259
00260 list_push_back (&int_devices, &pd->int_peer);
00261
00262
00263 if (!intr_is_registered (int_vec))
00264 intr_register_ext (int_vec, pci_interrupt, "PCI");
00265 }
00266
00267 void
00268 pci_unregister_irq (struct pci_dev *pd)
00269 {
00270 ASSERT (pd != NULL);
00271
00272 intr_disable ();
00273 list_remove (&pd->int_peer);
00274 intr_enable ();
00275
00276 pd->irq_handler = NULL;
00277 pd->irq_handler_aux = NULL;
00278 }
00279
00280 size_t
00281 pci_io_size (struct pci_io *pio)
00282 {
00283 ASSERT (pio != NULL);
00284
00285 return pio->size;
00286 }
00287
00288 void
00289 pci_reg_write32 (struct pci_io *pio, int reg, uint32_t data)
00290 {
00291 ASSERT (pio != NULL);
00292 ASSERT ((unsigned) reg < pio->size);
00293
00294 if (pio->type == PCI_IO_MEM)
00295 {
00296 *((uint32_t *) (pio->addr.ptr + reg)) = data;
00297 }
00298 else if (pio->type == PCI_IO_PORT)
00299 {
00300 outl (pio->addr.port + reg, data);
00301 }
00302 else
00303 PANIC ("pci: Invalid IO type\n");
00304 }
00305
00306 void
00307 pci_reg_write16 (struct pci_io *pio, int reg, uint16_t data)
00308 {
00309 ASSERT (pio != NULL);
00310 ASSERT ((unsigned) reg < pio->size);
00311
00312 if (pio->type == PCI_IO_MEM)
00313 {
00314 *((uint16_t *) (pio->addr.ptr + reg)) = data;
00315 }
00316 else if (pio->type == PCI_IO_PORT)
00317 {
00318 outw (pio->addr.port + reg, data);
00319 }
00320 else
00321 PANIC ("pci: Invalid IO type\n");
00322 }
00323
00324 void
00325 pci_reg_write8 (struct pci_io *pio, int reg, uint8_t data)
00326 {
00327 ASSERT (pio != NULL);
00328 ASSERT ((unsigned) reg < pio->size);
00329
00330 if (pio->type == PCI_IO_MEM)
00331 {
00332 *((uint8_t *) (pio->addr.ptr + reg)) = data;
00333 }
00334 else if (pio->type == PCI_IO_PORT)
00335 {
00336 outb (pio->addr.port + reg, data);
00337 }
00338 else
00339 PANIC ("pci: Invalid IO type\n");
00340 }
00341
00342 uint32_t
00343 pci_reg_read32 (struct pci_io *pio, int reg)
00344 {
00345 uint32_t ret;
00346
00347 ASSERT (pio != NULL);
00348 ASSERT ((unsigned) reg < pio->size);
00349
00350 if (pio->type == PCI_IO_MEM)
00351 {
00352 ret = *((uint32_t *) (pio->addr.ptr + reg));
00353 }
00354 else if (pio->type == PCI_IO_PORT)
00355 {
00356 ret = inl (pio->addr.port + reg);
00357 }
00358 else
00359 PANIC ("pci: Invalid IO type\n");
00360
00361 return ret;
00362 }
00363
00364 uint16_t
00365 pci_reg_read16 (struct pci_io * pio, int reg)
00366 {
00367 uint16_t ret;
00368
00369 ASSERT (pio != NULL);
00370 ASSERT ((unsigned) reg < pio->size);
00371
00372 ret = 0;
00373 if (pio->type == PCI_IO_MEM)
00374 {
00375 ret = *((uint16_t *) (pio->addr.ptr + reg));
00376 }
00377 else if (pio->type == PCI_IO_PORT)
00378 {
00379 ret = inw (pio->addr.port + reg);
00380 }
00381 else
00382 PANIC ("pci: Invalid IO type\n");
00383
00384 return ret;
00385
00386 }
00387
00388 uint8_t
00389 pci_reg_read8 (struct pci_io * pio, int reg)
00390 {
00391 uint8_t ret;
00392
00393 ASSERT (pio != NULL);
00394 ASSERT ((unsigned) reg < pio->size);
00395
00396 if (pio->type == PCI_IO_MEM)
00397 {
00398 ret = *((uint8_t *) (pio->addr.ptr + reg));
00399 }
00400 else if (pio->type == PCI_IO_PORT)
00401 {
00402 ret = inb (pio->addr.port + reg);
00403 }
00404 else
00405 PANIC ("pci: Invalid IO type\n");
00406
00407 return ret;
00408 }
00409
00410 void
00411 pci_read_in (struct pci_io *pio UNUSED, int off UNUSED, size_t size UNUSED,
00412 void *buf UNUSED)
00413 {
00414 PANIC ("pci_read_in: STUB");
00415 }
00416
00417 void
00418 pci_write_out (struct pci_io *pio UNUSED, int off UNUSED, size_t size UNUSED,
00419 const void *buf UNUSED)
00420 {
00421 PANIC ("pci_write_out: STUB");
00422 }
00423
00424 static void
00425 pci_write_config (int bus, int dev, int func, int reg,
00426 int size, uint32_t data)
00427 {
00428 int config_offset;
00429
00430 config_offset = pci_config_offset (bus, dev, func, reg);
00431
00432 outl (PCI_REG_ADDR, config_offset);
00433
00434 switch (size)
00435 {
00436 case 1:
00437 outb (PCI_REG_DATA + (reg & 3), data);
00438 break;
00439
00440 case 2:
00441 outw (PCI_REG_DATA + (reg & 3), data);
00442 break;
00443
00444 case 4:
00445 outl (PCI_REG_DATA, data);
00446 break;
00447 }
00448 }
00449
00450 static uint32_t
00451 pci_read_config (int bus, int dev, int func, int reg, int size)
00452 {
00453 uint32_t ret;
00454 int config_offset;
00455
00456 config_offset = pci_config_offset (bus, dev, func, reg);
00457
00458 outl (PCI_REG_ADDR, config_offset);
00459
00460 switch (size)
00461 {
00462 case 1:
00463 ret = inb (PCI_REG_DATA);
00464 break;
00465 case 2:
00466 ret = inw (PCI_REG_DATA);
00467 break;
00468 case 4:
00469 ret = inl (PCI_REG_DATA);
00470 break;
00471 default:
00472 PANIC ("pci: Strange config read size\n");
00473 }
00474
00475 return ret;
00476 }
00477
00478
00479 static void
00480 pci_read_all_config (int bus, int dev, int func,
00481 struct pci_config_header *pch)
00482 {
00483 unsigned int i;
00484 for (i = 0; i < ((sizeof (struct pci_config_header) + 3) & ~3) / 4; i++)
00485 {
00486 ((uint32_t *) pch)[i] = pci_read_config (bus, dev, func, i * 4, 4);
00487 }
00488 }
00489
00490
00492 static int
00493 pci_scan_bus (int bus)
00494 {
00495 int dev;
00496 int max_bus;
00497
00498 max_bus = 0;
00499
00500 for (dev = 0; dev < PCI_MAX_DEV_PER_BUS; dev++)
00501 {
00502 struct pci_config_header pch;
00503 int func_cnt, func;
00504
00505 pci_read_all_config (bus, dev, 0, &pch);
00506
00507 if (pch.pci_vendor_id == PCI_VENDOR_INVALID)
00508 continue;
00509
00510 func_cnt = 8;
00511 if (!(pch.pci_header & PCI_HEADER_MULTIFUNC))
00512 {
00513 func_cnt = 1;
00514 }
00515
00516 for (func = 0; func < func_cnt; func++)
00517 {
00518 int retbus;
00519 retbus = pci_probe (bus, dev, func, &pch);
00520 if (retbus > max_bus)
00521 max_bus = retbus;
00522 }
00523 }
00524
00525 return max_bus;
00526 }
00527
00528
00529
00530
00531
00532 static int
00533 pci_probe (int bus, int dev, int func, struct pci_config_header *ph)
00534 {
00535 struct pci_dev *pd;
00536
00537 if (func != 0)
00538 {
00539 pci_read_all_config (bus, dev, func, ph);
00540 if (ph->pci_vendor_id == PCI_VENDOR_INVALID)
00541 return bus;
00542 }
00543
00544 pd = malloc (sizeof (struct pci_dev));
00545 memcpy (&pd->pch, ph, sizeof (struct pci_config_header));
00546 pd->irq_handler = NULL;
00547 pd->irq_handler_aux = NULL;
00548 pd->bus = bus;
00549 pd->dev = dev;
00550 pd->func = func;
00551
00552 list_init (&pd->io_ranges);
00553 list_push_back (&devices, &pd->peer);
00554
00555
00556 if (ph->pci_major == PCI_MAJOR_BRIDGE)
00557 {
00558 if (ph->pci_minor == PCI_MINOR_PCI)
00559 return pci_pci_bridge (pd);
00560 }
00561
00562 pci_setup_io (pd);
00563 pci_power_on (pd);
00564
00565 return bus;
00566 }
00567
00568 static void
00569 pci_setup_io (struct pci_dev *pd)
00570 {
00571 int i;
00572 for (i = 0; i < PCI_BASE_COUNT; i++)
00573 {
00574 uint32_t tmp;
00575 struct pci_io *pio;
00576
00577 if (pd->pch.pci_base_reg[i] == 0)
00578 {
00579 continue;
00580 }
00581
00582
00583 pci_write_config (pd->bus, pd->dev, pd->func,
00584 offsetof (struct pci_config_header, pci_base_reg[i]),
00585 4, ~0);
00586
00587 tmp =
00588 pci_read_config (pd->bus, pd->dev, pd->func,
00589 offsetof (struct pci_config_header, pci_base_reg[i]),
00590 4);
00591
00592
00593 pci_write_config (pd->bus, pd->dev, pd->func,
00594 offsetof (struct pci_config_header, pci_base_reg[i]),
00595 4, pd->pch.pci_base_reg[i]);
00596
00597 pio = malloc (sizeof (struct pci_io));
00598 pio->dev = pd;
00599
00600 if (tmp & PCI_BASEADDR_IO)
00601 {
00602 pio->type = PCI_IO_PORT;
00603 pio->size = (uint16_t) ((~tmp + 1) & 0xffff) + 1;
00604 pio->addr.port = pd->pch.pci_base_reg[i] & ~1;
00605 }
00606 else
00607 {
00608 uint32_t ofs;
00609
00610 pio->type = PCI_IO_MEM;
00611 pio->size = ROUND_UP ((~tmp + 1), PGSIZE);
00612 ofs = (pd->pch.pci_base_reg[i] & 0xfffffff0 & PGMASK);
00613 pio->addr.ptr = pci_alloc_mem ((void *) pd->pch.pci_base_reg[i],
00614 pio->size / PGSIZE);
00615 if (pio->addr.ptr == NULL)
00616 {
00617 printf ("PCI: %d pages for %d:%d.%d failed - may not work\n",
00618 pio->size / PGSIZE, pd->bus, pd->dev, pd->func);
00619 free (pio);
00620 pio = NULL;
00621 }
00622 else
00623 {
00624 pio->addr.ptr = (void *) ((uintptr_t) pio->addr.ptr + ofs);
00625 }
00626 }
00627
00628
00629 if (pio != NULL)
00630 list_push_back (&pd->io_ranges, &pio->peer);
00631 }
00632
00633 }
00634
00635 static void
00636 pci_power_on (struct pci_dev *pd UNUSED)
00637 {
00638
00639 }
00640
00641 static int
00642 pci_pci_bridge (struct pci_dev *pd)
00643 {
00644 int max_bus;
00645 uint16_t command;
00646
00647
00648 command = pd->pch.pci_command;
00649 command &= ~0x3;
00650 pci_write_config (pd->bus, pd->dev, pd->func,
00651 offsetof (struct pci_config_header, pci_command),
00652 2, command);
00653 pd->pch.pci_command = command;
00654
00655
00656 pci_write_config (pd->bus, pd->dev, pd->func, 0x18, 1, pd->bus);
00657
00658 pci_write_config (pd->bus, pd->dev, pd->func, 0x19, 1, pd->bus + 1);
00659
00660
00661 pci_write_config (pd->bus, pd->dev, pd->func, 0x1a, 1, 0xff);
00662
00663
00664 max_bus = pci_scan_bus (pd->bus + 1);
00665
00666
00667 pci_write_config (pd->bus, pd->dev, pd->func, 0x1a, 1, max_bus);
00668
00669
00670 command |= 0x03;
00671 pci_write_config (pd->bus, pd->dev, pd->func,
00672 offsetof (struct pci_config_header, pci_command),
00673 2, command);
00674 pd->pch.pci_command = command;
00675
00676 return max_bus;
00677 }
00678
00679
00680 static void
00681 pci_interrupt (struct intr_frame *frame)
00682 {
00683 struct list_elem *e;
00684 int int_line;
00685
00686 int_line = frame->vec_no - 0x20;
00687 e = list_begin (&int_devices);
00688 while (e != list_end (&int_devices))
00689 {
00690 struct pci_dev *pd;
00691
00692 pd = list_entry (e, struct pci_dev, int_peer);
00693 if (pd->pch.pci_int_line == int_line)
00694 pd->irq_handler (pd->irq_handler_aux);
00695 e = list_next (e);
00696 }
00697 }
00698
00699
00700 void
00701 pci_print_stats (void)
00702 {
00703 struct list_elem *e;
00704
00705 e = list_begin (&devices);
00706 while (e != list_end (&devices))
00707 {
00708 struct pci_dev *pd;
00709
00710 pd = list_entry (e, struct pci_dev, peer);
00711 pci_print_dev_info (pd);
00712
00713 e = list_next (e);
00714 }
00715 }
00716
00717 static void
00718 pci_print_dev_info (struct pci_dev *pd)
00719 {
00720 printf ("PCI Device %d:%d.%d (%x,%x): %s - %s (%s) IRQ %d\n",
00721 pd->bus, pd->dev, pd->func,
00722 pd->pch.pci_vendor_id,
00723 pd->pch.pci_device_id,
00724 pci_lookup_vendor (pd->pch.pci_vendor_id),
00725 pci_lookup_device (pd->pch.pci_vendor_id, pd->pch.pci_device_id),
00726 pci_lookup_class (pd->pch.pci_major, pd->pch.pci_minor,
00727 pd->pch.pci_interface), pd->pch.pci_int_line);
00728 }
00729
00730 void
00731 pci_mask_irq (struct pci_dev *pd)
00732 {
00733 intr_irq_mask (pd->pch.pci_int_line);
00734 }
00735
00736 void
00737 pci_unmask_irq (struct pci_dev *pd)
00738 {
00739 intr_irq_unmask (pd->pch.pci_int_line);
00740 }
00741
00742 void
00743 pci_write_config16 (struct pci_dev *pd, int off, uint16_t data)
00744 {
00745 pci_write_config (pd->bus, pd->dev, pd->func, off, 2, data);
00746 }
00747
00748 void
00749 pci_write_config32 (struct pci_dev *pd, int off, uint32_t data)
00750 {
00751 pci_write_config (pd->bus, pd->dev, pd->func, off, 4, data);
00752 }
00753
00754 void
00755 pci_write_config8 (struct pci_dev *pd, int off, uint8_t data)
00756 {
00757 pci_write_config (pd->bus, pd->dev, pd->func, off, 1, data);
00758 }
00759
00760 uint8_t
00761 pci_read_config8 (struct pci_dev *pd, int off)
00762 {
00763 return pci_read_config (pd->bus, pd->dev, pd->func, off, 1);
00764 }
00765
00766 uint16_t
00767 pci_read_config16 (struct pci_dev * pd, int off)
00768 {
00769 return pci_read_config (pd->bus, pd->dev, pd->func, off, 2);
00770 }
00771
00772 uint32_t
00773 pci_read_config32 (struct pci_dev * pd, int off)
00774 {
00775 return pci_read_config (pd->bus, pd->dev, pd->func, off, 4);
00776 }
00777
00778
00780 static void *
00781 pci_alloc_mem (void *phys_ptr, int pages)
00782 {
00783 void *vaddr;
00784 int i;
00785
00786 phys_ptr = (void *) ((uintptr_t) phys_ptr & ~PGMASK);
00787
00788
00789 if ((unsigned) (num_pci_pages + pages) >= (unsigned) PCI_ADDR_ZONE_PAGES)
00790 {
00791 return NULL;
00792 }
00793
00794
00795 for (i = 0; i < pages; i++)
00796 {
00797 uint32_t pte_idx = (num_pci_pages + i) % 1024;
00798 uint32_t pde_idx = (num_pci_pages + i) / 1024;
00799 uint32_t *pt;
00800 uint32_t pte;
00801
00802 pde_idx += pd_no ((void *) PCI_ADDR_ZONE_BEGIN);
00803 pte = ((uint32_t) phys_ptr + (i * PGSIZE)) | PTE_P | PTE_W | PTE_CD;
00804 pt = (uint32_t *) (ptov (base_page_dir[pde_idx] & ~PGMASK));
00805 pt[pte_idx] = pte;
00806 }
00807
00808 vaddr = (void *) (PCI_ADDR_ZONE_BEGIN + (num_pci_pages * PGSIZE));
00809 num_pci_pages += pages;
00810
00811 return vaddr;
00812 }