Changeset 167 for soft/giet_vm/boot/boot_handler.c
- Timestamp:
- Jul 16, 2012, 10:26:27 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/boot/boot_handler.c
r165 r167 31 31 // As most applications use only a limited number of segments, the number of PT2s 32 32 // actually used by a given virtual space is generally smaller than 2048, and is 33 // defined in the MAPPING_INFO_BINARY data structure (using the length field). 34 // The value is calculated and put in _max_pt2 indexed by the vspace_id. 35 // The physical alignment constraints, is ensured by the align flag in the MAPPING_INFO 36 // structure. 33 // defined by the (GIET_NB_PT2_MAX) configuration parameter. 37 34 // The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter. 38 35 // 39 // Each page table (one page table per virtual space) is monolithic: 40 // - a first 8K aligned PT1[2148] array, indexed by the (ix1) field of VPN. 36 // Each page table (one page table per virtual space) is monolithic, and 37 // contains one PT1 and (GIET_NB_PT2_MAX) PT2s. The PT1 is addressed using the ix1 field 38 // (11 bits) of the VPN, and the selected PT2 is addressed using the ix2 field (9 bits). 39 // - PT1[2048] : a first 8K aligned array of unsigned int, indexed by the (ix1) field of VPN. 40 // Each entry in the PT1 contains a 32 bits PTD. The MSB bit PTD[31] is 41 // the PTD valid bit, and LSB bits PTD[19:0] are the 20 MSB bits of the physical base 42 // address of the selected PT2. 41 43 // The PT1 contains 2048 PTD of 4 bytes => 8K bytes. 42 // - an aray of array PT2[1024][_max_pt2[vspace_id]], indexed by 43 // the (ix2) field of the VPN, and by the PT2 index (pt2_id). 44 // Each PT2 contains 512 PTE2 of 8bytes => 4Kbytes * _max_pt2[vspace_id] 45 // The size of each page table is 8K + (_max_pt2[vspace_id])*4K bytes. 46 // All page tables must be stored in the seg_kernel_pt segment (at address 47 // seg_kernel_pt_base) 44 // - PT2[1024][GIET_NB_PT2_MAX] : an array of array of unsigned int. 45 // Each PT2[1024] must be 4K aligned, and each entry in a PT2 contains two unsigned int: 46 // the first word contains the protection flags, and the second word contains the PPN. 47 // Each PT2 contains 512 PTE2 of 8bytes => 4K bytes. 48 // The total size of a page table is finally = 8K + (GIET_NB_PT2_MAX)*4K bytes. 48 49 //////////////////////////////////////////////////////////////////////////////////// 49 50 … … 55 56 #include <stdarg.h> 56 57 57 58 58 #if !defined(GIET_NB_VSPACE_MAX) 59 59 # error The GIET_NB_VSPACE_MAX value must be defined in the 'giet_config.h' file ! 60 60 #endif 61 61 62 #if !defined(GIET_NB_PT2_MAX) 63 # error The GIET_NB_PT2_MAX value must be defined in the 'giet_config.h' file ! 64 #endif 65 62 66 //////////////////////////////////////////////////////////////////////////// 63 67 // Page Tables global variables … … 66 70 // Next free PT2 index array 67 71 unsigned int _next_free_pt2[GIET_NB_VSPACE_MAX] = 68 { [0 ... GIET_NB_VSPACE_MAX-1] = 0 };69 70 // Max number of PT2 array71 unsigned int _max_pt2[GIET_NB_VSPACE_MAX] =72 72 { [0 ... GIET_NB_VSPACE_MAX-1] = 0 }; 73 73 … … 439 439 // allocation), this function checks a possible overflow of the PT2 array. 440 440 // 441 // The parametre global is a boolean taht indicatewether a global vseg is441 // The global parameter is a boolean indicating wether a global vseg is 442 442 // being mapped. 443 443 ////////////////////////////////////////////////////////////////////////////// … … 445 445 unsigned int vpn, 446 446 unsigned int flags, 447 unsigned int ppn, 448 unsigned char global ) 447 unsigned int ppn ) 449 448 { 450 449 unsigned int ix1; … … 458 457 ix2 = vpn & 0x1FF; // 9 bits 459 458 460 461 unsigned int max_pt2 = _max_pt2[vspace_id]; 462 if(max_pt2 == 0) 463 { 464 boot_puts("Unfound page table for vspace "); 465 boot_putw(vspace_id); 466 boot_puts("\n"); 467 boot_exit(); 468 } 469 470 page_table_t* pt = (page_table_t *)_ptabs[vspace_id]; 459 page_table_t* pt = (page_table_t *)_ptabs[vspace_id]; 471 460 if ( (pt->pt1[ix1] & PTE_V) == 0 ) // set a new PTD in PT1 472 461 { 473 462 pt2_id = _next_free_pt2[vspace_id]; 474 if ( pt2_id == max_pt2)463 if ( pt2_id == GIET_NB_PT2_MAX ) 475 464 { 476 465 boot_puts("\n[BOOT ERROR] in boot_add_pte() function\n"); … … 557 546 vpn, 558 547 flags, 559 ppn, 560 0 ); 548 ppn ); 561 549 vpn++; 562 550 ppn++; … … 593 581 vpn, 594 582 flags, 595 ppn, 596 1 ); 583 ppn ); 597 584 vpn++; 598 585 ppn++; … … 616 603 // This function compute the physical base address for a vseg 617 604 // as specified in the mapping info data structure. 618 // It updates the pbase field of the vseg. 619 // It updates the page allocator (nextfreepage field of the pseg), 620 // and checks a possible pseg overflow. 605 // It updates the pbase and the length fields of the vseg. 606 // It updates the pbase and vbase fields of all vobjs in the vseg. 607 // It updates the next_base field of the pseg. 608 // It checks a possible pseg overflow. 621 609 // It is a global vseg if vspace_id = (-1) 622 610 /////////////////////////////////////////////////////////////////////////// … … 641 629 else // unconstrained mapping 642 630 { 643 vseg->pbase = pseg->base + (pseg->next_free_page<<12); 631 vseg->pbase = pseg->next_base; 632 633 // test alignment constraint 634 if ( vobj[vseg->vobj_offset].align ) 635 { 636 vseg->pbase = align_to( vseg->pbase, vobj[vseg->vobj_offset].align ); 637 } 644 638 } 645 639 646 // loop on vobjs to computes the length of the vseg, 647 // initialise the vaddr and paddr fields of all vobjs, 648 // and initialise the page table pointers array 640 // loop on vobjs to (1) computes the length of the vseg, 641 // (2) initialise the vaddr and paddr fields of all vobjs, 642 // (3) initialise the page table pointers array 643 649 644 cur_vaddr = vseg->vbase; 650 645 cur_paddr = vseg->pbase; … … 659 654 } 660 655 661 // set vaddr/paddr 656 // set vaddr/paddr for current vobj 662 657 vobj[vobj_id].vaddr = cur_vaddr; 663 658 vobj[vobj_id].paddr = cur_paddr; … … 667 662 cur_paddr += vobj[vobj_id].length; 668 663 669 // initialise _ptabs[] and _max_pt2[]664 // initialise _ptabs[] if current vobj is a PTAB 670 665 if ( vobj[vobj_id].type == VOBJ_TYPE_PTAB ) 671 666 { 672 if(vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE ) ) // max_pt2 >= 1667 if(vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE*GIET_NB_PT2_MAX) ) 673 668 { 674 669 boot_puts( "\n[BOOT ERROR] in boot_vseg_map() function: " ); … … 684 679 boot_exit(); 685 680 } 686 _ptabs[vspace_id] = (page_table_t*)vobj[vobj_id].paddr; 687 _max_pt2[vspace_id] = (vobj[vobj_id].length - PT1_SIZE) / PT2_SIZE; 688 } 689 } 681 _ptabs[vspace_id] = (page_table_t*)vobj[vobj_id].paddr; 682 } 683 } // end for vobjs 690 684 691 685 //set the vseg length 692 unsigned int plength = pseg->length; 693 unsigned int vlength = cur_paddr - vseg->pbase; 694 vseg->length = align_to(vlength, 12); 686 vseg->length = align_to( (cur_paddr - vseg->pbase), 12); 695 687 696 688 // checking pseg overflow 697 689 if ( (vseg->pbase < pseg->base) || 698 ((vseg->pbase + v length) > (pseg->base + plength)) )690 ((vseg->pbase + vseg->length) > (pseg->base + pseg->length)) ) 699 691 { 700 692 boot_puts("\n[BOOT ERROR] in boot_vseg_map() function\n"); 701 boot_puts("impossible identitymapping for virtual segment: ");693 boot_puts("impossible mapping for virtual segment: "); 702 694 boot_puts( vseg->name ); 703 695 boot_puts("\n"); … … 717 709 } 718 710 719 // computes number of pages 720 pages = vseg->length >> 12; 721 if ( (vseg->length & 0xFFF) != 0 ) pages++; 722 723 // set the next free physical address 724 if ( vseg->ident != 0 ) 725 ; // nothing to do 726 else 727 pseg->next_free_page = pseg->next_free_page + pages; 711 // set the next_base field in vseg 712 if ( vseg->ident == 0 ) 713 pseg->next_base = vseg->pbase + vseg->length; 728 714 729 715 #if BOOT_DEBUG_PT 730 boot_puts("- vseg ");731 716 boot_puts( vseg->name ); 732 boot_puts(" : vbase = "); 717 boot_puts(" : len = "); 718 boot_putw( vseg->length ); 719 boot_puts(" / vbase = "); 733 720 boot_putw( vseg->vbase ); 734 721 boot_puts(" / pbase = "); … … 816 803 for ( pseg_id = 0 ; pseg_id < header->psegs ; pseg_id++ ) 817 804 { 818 pseg[pseg_id].next_ free_page = 0;805 pseg[pseg_id].next_base = pseg[pseg_id].base; 819 806 } 820 807 … … 860 847 861 848 #if BOOT_DEBUG_PT 862 boot_puts(" >>> page table physical address = ");863 boot_putw((unsigned )_ptabs[vspace_id]);849 boot_puts("\n>>> page table physical address = "); 850 boot_putw((unsigned int)_ptabs[vspace_id]); 864 851 boot_puts("\n"); 865 852 #endif
Note: See TracChangeset
for help on using the changeset viewer.