1/* 2 * Copyright (c) 2010-2010 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 2.0 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23#ifdef KERNEL 24 25#include <IOKit/pci/IOPCIPrivate.h> 26#include <IOKit/pci/IOPCIConfigurator.h> 27 28#else 29 30/* 31cc IOPCIRange.cpp -o /tmp/pcirange -Wall -framework IOKit -framework CoreFoundation -arch i386 -g -lstdc++ 32*/ 33 34#include <assert.h> 35#include <CoreFoundation/CoreFoundation.h> 36#include <IOKit/IOKitLib.h> 37#include <IOKit/IOKitKeys.h> 38 39#include "IOKit/pci/IOPCIConfigurator.h" 40#define panic(x) printf(x) 41#define kprintf(fmt, args...) printf(fmt, ## args) 42 43#endif 44 45IOPCIScalar IOPCIScalarAlign(IOPCIScalar num, IOPCIScalar alignment) 46{ 47 return (num + (alignment - 1) & ~(alignment - 1)); 48} 49 50IOPCIScalar IOPCIScalarTrunc(IOPCIScalar num, IOPCIScalar alignment) 51{ 52 return (num & ~(alignment - 1)); 53} 54 55IOPCIRange * IOPCIRangeAlloc(void) 56{ 57#ifdef KERNEL 58 return (IONew(IOPCIRange, 1)); 59#else 60 return ((IOPCIRange *) malloc(sizeof(IOPCIRange))); 61#endif 62} 63 64void IOPCIRangeFree(IOPCIRange * range) 65{ 66// memset(range, 0xBB, sizeof(*range)); 67#ifdef KERNEL 68 IODelete(range, IOPCIRange, 1); 69#else 70 free(range); 71#endif 72} 73 74void IOPCIRangeInit(IOPCIRange * range, uint32_t type, 75 IOPCIScalar start, IOPCIScalar size, IOPCIScalar alignment) 76{ 77 bzero(range, sizeof(*range)); 78 range->type = type; 79 range->start = start; 80// range->size = 0; 81 range->proposedSize = size; 82 range->totalSize = size; 83 range->end = start; 84// range->zero = 0; 85 range->alignment = alignment ? alignment : size; 86// range->minAddress = 0; 87 range->maxAddress = 0xFFFFFFFF; 88 range->allocations = (IOPCIRange *) &range->end; 89} 90 91void IOPCIRangeInitAlloc(IOPCIRange * range, uint32_t type, 92 IOPCIScalar start, IOPCIScalar size, IOPCIScalar alignment) 93{ 94 IOPCIRangeInit(range, type, start, size, alignment); 95 range->size = range->proposedSize; 96 range->end = range->start + range->size; 97} 98 99bool IOPCIRangeListAddRange(IOPCIRange ** rangeList, 100 uint32_t type, 101 IOPCIScalar start, 102 IOPCIScalar size, 103 IOPCIScalar alignment) 104{ 105 IOPCIRange * range; 106 IOPCIRange * nextRange; 107 IOPCIRange ** prev; 108 IOPCIScalar end; 109 bool result = true; 110 bool alloc = true; 111 112 end = start + size; 113 for (prev = rangeList; (range = *prev); prev = &range->next) 114 { 115 if (((start >= range->start) && (start < range->end)) 116 || ((end > range->start) && (end <= range->end)) 117 || ((start < range->start) && (end > range->end))) 118 { 119 range = NULL; 120 result = false; 121 break; 122 } 123 if (end == range->start) 124 { 125 range->start = start; 126 range->size = range->end - range->start; 127 range->proposedSize = range->size; 128 alloc = false; 129 break; 130 } 131 if (start == range->end) 132 { 133 if ((nextRange = range->next) && (nextRange->start == end)) 134 { 135 if (nextRange->allocations != (IOPCIRange *) &nextRange->end) 136 assert(false); 137 end = nextRange->end; 138 range->next = nextRange->next; 139 IOPCIRangeFree(nextRange); 140 } 141 range->end = end; 142 range->size = end - range->start; 143 range->proposedSize = range->size; 144 alloc = false; 145 break; 146 } 147 if (range->start > end) 148 { 149 alloc = true; 150 break; 151 } 152 } 153 154 if (result && alloc) 155 { 156 nextRange = IOPCIRangeAlloc(); 157 IOPCIRangeInitAlloc(nextRange, type, start, size, alignment); 158 nextRange->next = range; 159 *prev = nextRange; 160 } 161 162 return (result); 163} 164 165IOPCIScalar IOPCIRangeListCollapse(IOPCIRange * headRange, IOPCIScalar alignment) 166{ 167 IOPCIScalar total = 0; 168 169 while (headRange) 170 { 171 total += IOPCIRangeCollapse(headRange, alignment); 172 headRange = headRange->next; 173 } 174 175 return (total); 176} 177 178IOPCIScalar IOPCIRangeCollapse(IOPCIRange * headRange, IOPCIScalar alignment) 179{ 180 IOPCIScalar start, end, saving; 181 IOPCIRange * range; 182 183 start = 0; 184 end = 0; 185 saving = headRange->size; 186 range = headRange->allocations; 187 do 188 { 189 // keep walking down the list 190 if (!range->size) 191 break; 192 if (!start) 193 start = range->start; 194 end = range->end; 195 range = range->nextSubRange; 196 } 197 while(true); 198 199 start = IOPCIScalarTrunc(start, alignment); 200 end = IOPCIScalarAlign(end, alignment); 201 202 if (!start) headRange->proposedSize = 0; 203 else 204 { 205 headRange->start = start; 206 headRange->end = end; 207 headRange->size = 208 headRange->proposedSize = end - start; 209 if (headRange->size > headRange->totalSize) 210 { 211 headRange->extendSize = headRange->size - headRange->totalSize; 212 } 213 else 214 { 215 headRange->extendSize = 0; 216 } 217 } 218 if (saving < headRange->proposedSize) panic("IOPCIRangeCollapse"); 219 saving -= headRange->proposedSize; 220 221 return (saving); 222} 223 224IOPCIScalar IOPCIRangeListLastFree(IOPCIRange * headRange, IOPCIScalar align) 225{ 226 IOPCIRange * next; 227 next = headRange; 228 while (next) 229 { 230 headRange = next; 231 next = next->next; 232 } 233 return (IOPCIRangeLastFree(headRange, align)); 234} 235 236IOPCIScalar IOPCIRangeLastFree(IOPCIRange * headRange, IOPCIScalar align) 237{ 238 IOPCIScalar last; 239 IOPCIRange * range; 240 241 range = headRange->allocations; 242 last = headRange->start; 243 do 244 { 245 // keep walking down the list 246 if (!range->size) break; 247 last = range->end; 248 range = range->nextSubRange; 249 } 250 while(true); 251 252 last = IOPCIScalarAlign(last, align); 253 if (headRange->end > last) 254 last = headRange->end - last; 255 else 256 last = 0; 257 258 return (last); 259} 260 261void IOPCIRangeOptimize(IOPCIRange * headRange) 262{ 263 IOPCIScalar free; 264 IOPCIScalar count; 265 IOPCIScalar chunk, bump, tail; 266 IOPCIScalar next, end; 267 IOPCIRange * range; 268 IOPCIRange * prev; 269 270 range = headRange->allocations; 271 prev = NULL; 272 free = 0; 273 count = 0; 274 do 275 { 276 if (prev) 277 { 278 assert(range->start >= prev->end); 279 free += (range->start - prev->end); 280 } 281 // eol 282 if (!range->size) break; 283 284 range->nextToAllocate = prev; 285 if ((kIOPCIRangeFlagMaximizeSize | kIOPCIRangeFlagMaximizeRoot | kIOPCIRangeFlagSplay) 286 & range->flags) count++; 287 prev = range; 288 range = range->nextSubRange; 289 } 290 while(true); 291 292 if (!free) return; 293 294 end = headRange->end; 295 for (range = prev; free && range; end = range->start, range = range->nextToAllocate) 296 { 297 if (!(kIOPCIRangeFlagRelocatable & range->flags)) continue; 298 299 chunk = 0; 300 if ((kIOPCIRangeFlagMaximizeSize | kIOPCIRangeFlagSplay) & range->flags) 301 { 302 chunk = free / count; 303 chunk = IOPCIScalarTrunc(chunk, range->alignment); 304 free -= chunk; 305 count--; 306 } 307 308 next = range->end; 309 if (end < next) panic("end"); 310 tail = IOPCIScalarTrunc(end - next, range->alignment); 311 if (chunk > tail) chunk = tail; 312 313 if (kIOPCIRangeFlagSplay & range->flags) 314 { 315 bump = tail - chunk; 316 range->end += bump; 317 range->start += bump; 318 } 319 else 320 { 321 range->size += chunk; 322 range->proposedSize = range->size; 323 range->end = end; 324 range->start = range->end - range->size; 325 } 326 327 if (range->start > headRange->end) panic("s>"); 328 if (range->start < headRange->start) panic("s<"); 329 if (range->end > headRange->end) panic("e>"); 330 if (range->end < headRange->start) panic("e<"); 331 } 332} 333 334void IOPCIRangeListOptimize(IOPCIRange * headRange) 335{ 336 IOPCIRange * next; 337 next = headRange; 338 while (next) 339 { 340 IOPCIRangeOptimize(next); 341 next = next->next; 342 } 343} 344 345bool IOPCIRangeListAllocateSubRange(IOPCIRange * headRange, 346 IOPCIRange * newRange, 347 IOPCIScalar newStart) 348{ 349 IOPCIScalar minSize, maxSize; 350 IOPCIScalar len, bestFit, waste; 351 IOPCIScalar pos, endPos; 352 IOPCIRange ** where = NULL; 353 IOPCIRange * whereNext = NULL; 354 IOPCIRange * range = NULL; 355 IOPCIRange ** prev; 356 357 minSize = newRange->size; 358 if (!minSize) minSize = newRange->proposedSize; 359 if (!minSize) panic("!minSize"); 360 if (!newStart) newStart = newRange->start; 361 362 bestFit = UINT64_MAX; 363 for (; headRange; headRange = headRange->next) 364 { 365 if (!headRange->size) continue; 366 367 maxSize = newRange->proposedSize; 368 if (!maxSize) panic("!maxSize"); 369 if (maxSize < minSize) minSize = maxSize; 370 371 pos = headRange->start; 372 prev = &headRange->allocations; 373 range = NULL; 374 do 375 { 376 if (range) 377 { 378 // onto next element 379 if (!range->size) 380 { 381 // end of list 382 range = NULL; 383 break; 384 } 385 pos = range->end; 386 prev = &range->nextSubRange; 387 } 388 range = *prev; 389 if (range == newRange) 390 { 391 // reallocate in place - treat as free 392 range = range->nextSubRange; 393 } 394 endPos = range->start; 395 396 // [pos,endPos] is free 397 waste = endPos - pos; 398 if (pos > newRange->maxAddress) pos = newRange->maxAddress; 399 if (endPos > newRange->maxAddress) endPos = newRange->maxAddress; 400 if (newStart) 401 { 402 if (newStart < pos) continue; 403 if (newStart >= endPos) continue; 404 pos = newStart; 405 } 406 else pos = IOPCIScalarAlign(pos, newRange->alignment); 407 if (kIOPCIRangeFlagMaximizeRoot & newRange->flags) 408 endPos = IOPCIScalarTrunc(endPos, newRange->alignment); 409 410 if (endPos < pos) continue; 411 412 len = endPos - pos; 413 if (len < minSize) continue; 414 if (len > maxSize) len = maxSize; 415 416 if (newStart 417 || (where && (newRange->start < newRange->minAddress) && (pos >= newRange->minAddress)) 418 || (len < maxSize) 419 || (kIOPCIRangeFlagMaximizeRoot & newRange->flags)) 420 { 421 } 422 else 423 { 424 if ((kIOPCIRangeFlagSplay | kIOPCIRangeFlagMaximizeSize) & newRange->flags) 425 { 426 // in biggest free area position 427 waste = UINT64_MAX - waste; 428 } 429 else 430 { 431 // least waste position 432 waste -= len; 433 } 434 if (where && (bestFit < waste)) continue; 435 bestFit = waste; 436 } 437 // best candidate, will queue prev->newRange->range 438 // new size to look for 439 minSize = len; 440 where = prev; 441 whereNext = range; 442 newRange->start = pos; 443 newRange->size = len; 444 newRange->end = pos + len; 445 446 if (newStart || !waste) 447 { 448 // use this if placed or zero waste 449 break; 450 } 451 } 452 while(true); 453 } 454 455 if (where) 456 { 457 if (kIOPCIRangeFlagMaximizeRoot & newRange->flags) newRange->proposedSize = newRange->size; 458 newRange->nextSubRange = whereNext; 459 *where = newRange; 460 } 461 462 return (where != NULL); 463} 464 465bool IOPCIRangeListDeallocateSubRange(IOPCIRange * headRange, 466 IOPCIRange * oldRange) 467{ 468 IOPCIRange * range = NULL; 469 IOPCIRange ** prev = NULL; 470 471 do 472 { 473 range = oldRange->allocations; 474 if (!range->size) 475 break; 476 IOPCIRangeListDeallocateSubRange(oldRange, range); 477 } 478 while(true); 479 480 for (range = NULL; 481 headRange && !range; 482 headRange = headRange->next) 483 { 484 prev = &headRange->allocations; 485 do 486 { 487 range = *prev; 488 if (range == oldRange) 489 break; 490 // keep walking down the list 491 if (!range->size) 492 { 493 range = NULL; 494 break; 495 } 496 } 497 while (prev = &range->nextSubRange, true); 498 } 499 500 if (range) 501 { 502 *prev = range->nextSubRange; 503 oldRange->nextSubRange = NULL; 504 oldRange->end = 0; 505// oldRange->proposedSize = oldRange->size; 506// oldRange->size = 0; 507// oldRange->extendSize = 0; 508 oldRange->start = 0; 509 } 510 511 return (range != 0); 512} 513 514void IOPCIRangeDump(IOPCIRange * head) 515{ 516 IOPCIRange * range; 517 uint32_t idx; 518 519 do 520 { 521 kprintf("head.start 0x%llx\n", head->start); 522 kprintf("head.size 0x%llx\n", head->size); 523 kprintf("head.end 0x%llx\n", head->end); 524 kprintf("head.alignment 0x%llx\n", head->alignment); 525 526 kprintf("allocs:\n"); 527 range = head->allocations; 528 idx = 0; 529 while (true) 530 { 531 if (range == (IOPCIRange *) &head->end) 532 { 533 kprintf("[end]\n"); 534 break; 535 } 536 kprintf("[%d].start 0x%llx\n", idx, range->start); 537 kprintf("[%d].size 0x%llx\n", idx, range->size); 538 kprintf("[%d].end 0x%llx\n", idx, range->end); 539 kprintf("[%d].alignment 0x%llx\n", idx, range->alignment); 540 idx++; 541 range = range->nextSubRange; 542 } 543 kprintf("------\n"); 544 } 545 while ((head = head->next)); 546 547 kprintf("------------------------------------\n"); 548} 549 550#ifndef KERNEL 551 552int main(int argc, char **argv) 553{ 554 IOPCIRange * head = NULL; 555 IOPCIRange * range; 556 IOPCIRange * requests = NULL; 557 IOPCIRange * elems[8]; 558 IOPCIScalar shrink; 559 size_t idx; 560 bool ok; 561 562 for (idx = 0; idx < sizeof(elems) / sizeof(elems[0]); idx++) 563 { 564 elems[idx] = IOPCIRangeAlloc(); 565 elems[idx]->maxAddress = 0xFFFFFFFFFFFFFFFFULL; 566 } 567 568#if 1 569 570 IOPCIRangeListAddRange(&head, 0, 0x00000000b5f00000, 0x0000000001100000, 0x0000000000400000); 571 572 range = elems[0]; 573 IOPCIRangeInit(range, 0, 0, 0x0000000000100000, 0x0000000000100000); 574 ok = IOPCIRangeListAllocateSubRange(head, range); 575 assert(ok); 576 577 range = elems[1]; 578 IOPCIRangeInit(range, 0, 0, 0x0000000000f00000, 0x400000); 579 range->flags |= kIOPCIRangeFlagRelocatable | kIOPCIRangeFlagSplay; 580 ok = IOPCIRangeListAllocateSubRange(head, range); 581 assert(ok); 582 583 IOPCIRangeDump(head); 584 585 IOPCIRangeListOptimize(head); 586 587 IOPCIRangeDump(head); 588 589 exit(0); 590 591#elif 0 592 593 uint32_t flags; 594 595 IOPCIRangeListAddRange(&head, 0, 0x25, 0x7, 1); 596 IOPCIRangeDump(head); 597 598 range = elems[0]; 599 IOPCIRangeInit(range, 0, 0x25, 1, 1); 600 ok = IOPCIRangeListAllocateSubRange(head, range); 601 assert(ok); 602 603 range = elems[1]; 604 IOPCIRangeInit(range, 0, 0, 6, 1); 605 range->size = 1; 606 range->flags |= kIOPCIRangeFlagMaximizeSize; 607 ok = IOPCIRangeListAllocateSubRange(head, range); 608 assert(ok); 609 assert(range->proposedSize == range->size); 610 IOPCIRangeDump(head); 611 exit(0); 612 613 range = elems[2]; 614 IOPCIRangeInit(range, 0, 0x7, 1, 1); 615 ok = IOPCIRangeListAllocateSubRange(head, range); 616 assert(ok); 617 618 range = elems[3]; 619 IOPCIRangeInit(range, 0, 0x6, 0x1, 1); 620 ok = IOPCIRangeListAllocateSubRange(head, range); 621 assert(ok); 622 623 range = elems[4]; 624 IOPCIRangeInit(range, 0, 0x8, 1, 1); 625 ok = IOPCIRangeListAllocateSubRange(head, range); 626 assert(ok); 627 628 629 630 range = elems[5]; 631 IOPCIRangeInit(range, 0, 0, 0xa, 1); 632 range->size = 9; 633 ok = IOPCIRangeListAllocateSubRange(head, range); 634 assert(0xa == range->size); 635 assert(ok); 636exit(0); 637 flags = kIOPCIRangeFlagRelocatable | kIOPCIRangeFlagSplay; 638// flags = kIOPCIRangeFlagRelocatable | kIOPCIRangeFlagMaximizeSize; 639 640 range = elems[2]; 641 IOPCIRangeInit(range, 0, 0, 0xe, 1); 642 range->flags |= flags; 643 ok = IOPCIRangeListAllocateSubRange(head, range); 644 assert(ok); 645 646 range = elems[3]; 647 IOPCIRangeInit(range, 0, 0, 0x7, 1); 648 range->flags |= flags; 649 ok = IOPCIRangeListAllocateSubRange(head, range); 650 assert(ok); 651 652 range = elems[4]; 653 IOPCIRangeInit(range, 0, 0, 0x7, 1); 654 range->flags |= flags; 655 ok = IOPCIRangeListAllocateSubRange(head, range); 656 assert(ok); 657 658 IOPCIRangeOptimize(head); 659 660 exit(0); 661#endif 662 663 664 665#if 0 666 IOPCIRangeListAddRange(&head, 0, 0,0, 1024*1024); 667 IOPCIRangeDump(head); 668 shrink = IOPCIRangeListLastFree(head, 1024*1024); 669 printf("IOPCIRangeListLastFree 0x%llx\n", shrink); 670exit(0); 671#endif 672 673#if 0 674 IOPCIRangeListAddRange(&head, 0, 0xa0800000, 0x500000, 0x100000); 675 676 range = elems[0]; 677 IOPCIRangeInit(range, 0, 0xa0800000, 0x40000, 0x40000); 678 ok = IOPCIRangeListAllocateSubRange(head, range); 679 assert(ok); 680 681 range = elems[1]; 682 IOPCIRangeInit(range, 0, 0xa0a00000, 0x400000, 0x100000); 683 ok = IOPCIRangeListAllocateSubRange(head, range); 684 assert(ok); 685 686 range->proposedSize = 0x300000; 687 ok = IOPCIRangeListAllocateSubRange(head, range); 688 assert(ok); 689// ok = IOPCIRangeListDeallocateSubRange(head, range); 690// assert(ok); 691 IOPCIRangeDump(head); 692 693 exit(0); 694#endif 695 696 IOPCIRangeListAddRange(&head, 0, 0x6, 0xfa, 1); 697 IOPCIRangeDump(head); 698 699 range = elems[4]; 700 range->start = 0x06; 701 range->proposedSize = 0x01; 702 range->alignment = 1; 703 ok = IOPCIRangeListAllocateSubRange(head, range); 704 assert(ok); 705 706 range = elems[3]; 707 range->start = 0x07; 708 range->proposedSize = 0x01; 709 range->alignment = 1; 710 ok = IOPCIRangeListAllocateSubRange(head, range); 711 assert(ok); 712 713 range = elems[1]; 714 range->start = 1*0x87; 715 range->size = 3; 716 range->proposedSize = 3; 717 range->alignment = 1; 718 range->flags = kIOPCIRangeFlagSplay; 719 ok = IOPCIRangeListAllocateSubRange(head, range); 720 assert(ok); 721 722 range = elems[2]; 723 range->start = 0; 724 range->proposedSize = 2; 725 range->alignment = 1; 726 range->flags = kIOPCIRangeFlagSplay; 727 ok = IOPCIRangeListAllocateSubRange(head, range); 728 assert(ok); 729 730 731 range = elems[5]; 732 range->start = 0; 733 range->proposedSize = 1; 734 range->alignment = 1; 735 range->flags = kIOPCIRangeFlagSplay; 736 ok = IOPCIRangeListAllocateSubRange(head, range); 737 assert(ok); 738 739 range = elems[6]; 740 range->start = 0; 741 range->proposedSize = 1; 742 range->alignment = 1; 743 range->flags = kIOPCIRangeFlagSplay; 744 ok = IOPCIRangeListAllocateSubRange(head, range); 745 assert(ok); 746 747 748 IOPCIRangeDump(head); 749 exit(0); 750 751 shrink = IOPCIRangeListLastFree(head, 1024); 752 printf("IOPCIRangeListLastFree 0x%llx\n", shrink); 753 exit(0); 754 755 idx = 0; 756 IOPCIRangeInit(elems[idx++], 0, 0, 1024*1024); 757 758 range = elems[0]; 759 ok = IOPCIRangeListAllocateSubRange(head, range); 760 printf("alloc(%d) [0x%llx, 0x%llx]\n", ok, range->start, range->size); 761 IOPCIRangeDump(head); 762 763 shrink = IOPCIRangeListCollapse(head, 1024*1024); 764 printf("Collapsed by 0x%llx\n", shrink); 765 IOPCIRangeDump(head); 766 exit(0); 767 768 769 IOPCIRangeListAddRange(&head, 0, 0xA0000000, 0x10000000); 770 IOPCIRangeListAddRange(&head, 0, 0x98000000, 0x08000000); 771 IOPCIRangeListAddRange(&head, 0, 0x90000000, 0x08000000); 772 IOPCIRangeListAddRange(&head, 0, 0xB0000000, 0x10000000); 773 774//exit(0); 775 776 777 idx = 0; 778 IOPCIRangeInit(elems[idx++], 0, 0x80001000, 0x1000); 779 IOPCIRangeInit(elems[idx++], 0, 0, 0x1000000); 780 IOPCIRangeInit(elems[idx++], 0, 0, 0x20000000); 781 IOPCIRangeInit(elems[idx++], 0, 0, 0x20000000); 782 IOPCIRangeInit(elems[idx++], 0, 0x80002000, 0x800); 783 IOPCIRangeInit(elems[idx++], 0, 0, 0x10000, 1); 784 785 for (idx = 0; idx < sizeof(elems) / sizeof(elems[0]); idx++) 786 { 787 if (elems[idx]->size) 788 IOPCIRangeAppendSubRange(&requests, elems[idx]); 789 } 790 791 printf("reqs:\n"); 792 range = requests; 793 idx = 0; 794 while (range) 795 { 796 printf("[%ld].start 0x%llx\n", idx, range->start); 797 printf("[%ld].size 0x%llx\n", idx, range->size); 798 printf("[%ld].end 0x%llx\n", idx, range->end); 799 printf("[%ld].alignment 0x%llx\n", idx, range->alignment); 800 idx++; 801 range = range->nextSubRange; 802 } 803 804 while ((range = requests)) 805 { 806 requests = range->nextSubRange; 807 ok = IOPCIRangeListAllocateSubRange(head, range); 808 printf("alloc(%d) [0x%llx, 0x%llx]\n", ok, range->start, range->size); 809 } 810 811 IOPCIRangeDump(head); 812 shrink = IOPCIRangeListCollapse(head, 1024*1024); 813 printf("Collapsed by 0x%llx\n", shrink); 814 IOPCIRangeDump(head); 815exit(0); 816 817 for (idx = 0; idx < sizeof(elems) / sizeof(elems[0]); idx++) 818 { 819 range = elems[idx]; 820 if (range->size && range->start) 821 { 822 ok = IOPCIRangeListDeallocateSubRange(head, range); 823 printf("dealloc(%d) [0x%llx, 0x%llx]\n", ok, range->start, range->size); 824 ok = IOPCIRangeListAllocateSubRange(head, range); 825 printf("alloc(%d) [0x%llx, 0x%llx]\n", ok, range->start, range->size); 826 } 827 } 828 829 // extend 830 range = elems[5]; 831 range->proposedSize = 2 * range->size; 832 ok = IOPCIRangeListAllocateSubRange(head, range); 833 printf("extalloc(%d) [0x%llx, 0x%llx]\n", ok, range->start, range->size); 834 range = elems[0]; 835 range->proposedSize = 2 * range->size; 836 ok = IOPCIRangeListAllocateSubRange(head, range); 837 printf("extalloc(%d) [0x%llx, 0x%llx]\n", ok, range->start, range->size); 838 range->proposedSize = 2 * range->size; 839 ok = IOPCIRangeListAllocateSubRange(head, range, range->start - range->size); 840 printf("extalloc(%d) [0x%llx, 0x%llx]\n", ok, range->start, range->size); 841 842 IOPCIRangeDump(head); 843 844 exit(0); 845} 846 847#endif 848