369 if(r != KErrNotFound) |
521 if(r != KErrNotFound) |
370 { |
522 { |
371 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc:dsc: ReadPartition() failed r=%d!", r)); |
523 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc:dsc: ReadPartition() failed r=%d!", r)); |
372 r = KErrCorrupt; |
524 r = KErrCorrupt; |
373 } |
525 } |
374 else if(partitionCount == 0) |
526 else if(iPartitionInfo->iPartitionCount == 0) |
375 { |
527 { |
376 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc:dsc: No supported partitions found!")); |
528 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc:dsc: No supported partitions found!")); |
377 r = KErrCorrupt; |
529 r = KErrCorrupt; |
378 } |
530 } |
379 else |
531 else |
380 r = KErrCompletion; |
532 r = KErrCompletion; |
381 } |
533 } |
|
534 |
|
535 |
|
536 if (iVersionInfoRead) |
|
537 { |
|
538 __KTRACE_OPT(KPBUSDRV, Kern::Printf("%d Version Headers - Register HAL entry", iVersionInfoItems )); |
|
539 //finished parsing the TOC register HAL function |
|
540 r = Kern::AddHalEntry(EHalGroupNandMedia, halFunction, this, ENandMediaDevice1); |
|
541 if (r==KErrNone) |
|
542 { |
|
543 __KTRACE_OPT(KPBUSDRV,Kern::Printf("DBB5PartitionInfo:Added HAL Entry %d",r)); |
|
544 r = KErrCompletion; //re-mark as completed |
|
545 } |
|
546 } |
382 |
547 |
383 // Notify medmmc that partitioninfo is complete |
548 // Notify medmmc that partitioninfo is complete |
384 iCallBack.CallBack(); |
549 iCallBack.CallBack(); |
385 |
550 |
386 // All potential partitions checked - KErrCompletion |
551 // All potential partitions checked - KErrCompletion |
387 // indicates that there are no more partitions to check |
552 // indicates that there are no more partitions to check |
388 r = (r == KErrCompletion) ? KErrNone : KErrNotReady; |
553 r = (r == KErrCompletion) ? KErrNone : KErrNotReady; |
|
554 __KTRACE_OPT(KPBUSDRV,Kern::Printf("<DBB5PartitionInfo:PartitionInfo Complete %d",r)); |
389 iDriver->PartitionInfoComplete(r); |
555 iDriver->PartitionInfoComplete(r); |
390 } |
556 } |
391 |
557 |
392 |
558 TInt DBB5PartitionInfo::CheckPartitionBoundaries(TInt aStart, TInt aEnd) |
393 TInt DBB5PartitionInfo::DecodePartitionInfo() |
559 { |
|
560 __ASSERT_ALWAYS(aStart >= 0,Kern::Fault("DBB5PartitionInfo:CPB aStart <0", __LINE__)); |
|
561 __ASSERT_ALWAYS(aEnd > 0,Kern::Fault("DBB5PartitionInfo:CPB aEnd <=0", __LINE__)); |
|
562 |
|
563 // Validate partition address boundaries |
|
564 TUint32 eMmcPartitionSizeInSectors = 0; |
|
565 TInt r = KErrNone; |
|
566 |
|
567 if (aStart != aEnd) |
|
568 { |
|
569 // At least one entry for a supported partition found |
|
570 r = GetPartitionSizeInSectors(iSelectedPartition, eMmcPartitionSizeInSectors); |
|
571 |
|
572 if(r != KErrNone) |
|
573 { |
|
574 __KTRACE_OPT(KPBUSDRV, Kern::Printf("DBB5PartitionInfo:CPB: Could not retrieve size for eMMC partition 0x%02X", iSelectedPartition)); |
|
575 r = KErrCorrupt; |
|
576 } |
|
577 |
|
578 |
|
579 // Check that the eMmcPartition address space boundary is not exceeded by the last partition |
|
580 if(r == KErrNone) |
|
581 { |
|
582 TUint64 eMmcPartitionSize = eMmcPartitionSizeInSectors * KSectorSize; |
|
583 |
|
584 TPartitionEntry& part = iPartitionInfo->iEntry[aEnd - 1]; |
|
585 |
|
586 if(((TUint64)(part.iPartitionBaseAddr + part.iPartitionLen)) > eMmcPartitionSize) |
|
587 { |
|
588 __KTRACE_OPT(KPBUSDRV, Kern::Printf("DBB5PartitionInfo:CPB: Partition #%d exceeds eMmc address space", aEnd)); |
|
589 r = KErrCorrupt; |
|
590 } |
|
591 } |
|
592 |
|
593 if(r == KErrNone) |
|
594 { |
|
595 // Go through all BB5 partition entries on this eMMC partition and check boundaries |
|
596 for(TInt i = aEnd - 1; i > aStart; i--) |
|
597 { |
|
598 const TPartitionEntry& curr = iPartitionInfo->iEntry[i]; |
|
599 TPartitionEntry& prev = iPartitionInfo->iEntry[i-1]; |
|
600 |
|
601 // Check if partitions overlap |
|
602 if(curr.iPartitionBaseAddr < (prev.iPartitionBaseAddr + prev.iPartitionLen)) |
|
603 { |
|
604 __KTRACE_OPT(KPBUSDRV, Kern::Printf("DBB5PartitionInfo:CPB: Overlapping partitions - check #%d", i)); |
|
605 r = KErrCorrupt; |
|
606 } |
|
607 } |
|
608 } |
|
609 } |
|
610 |
|
611 return r; |
|
612 } |
|
613 |
|
614 TInt DBB5PartitionInfo::DecodeBB5PartitionInfo() |
394 // |
615 // |
395 // Decode partition info that was read into internal buffer |
616 // Decode partition info that was read into internal buffer |
396 // |
617 // |
397 { |
618 { |
398 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">Mmc:PartitionInfo()")); |
619 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">DBB5PartitionInfo: DecodeBB5PartitionInfo(%d)",iPartitionInfo->iPartitionCount)); |
399 TInt& partitionCount = iPartitionInfo->iPartitionCount; |
620 TInt partitionCount = iPartitionInfo->iPartitionCount; |
|
621 TInt r = KErrNotFound; |
|
622 |
|
623 #ifdef __PRINT_RAW_ENTRIES |
|
624 Kern::Printf("BB5 Entry"); |
|
625 for (TUint i = 0; i < 512; i+=8) |
|
626 { |
|
627 Kern::Printf("%02x %02x %02x %02x %02x %02x %02x %02x", iIntBuf[i],iIntBuf[i+1],iIntBuf[i+2],iIntBuf[i+3],iIntBuf[i+4],iIntBuf[i+5],iIntBuf[i+6],iIntBuf[i+7]); |
|
628 } |
|
629 #endif |
|
630 |
|
631 // Try utilising the BB5 partitioning scheme |
|
632 BGAHSMMCPTN_PI_STR *partitionTable = (BGAHSMMCPTN_PI_STR*)(&iIntBuf[0]); |
|
633 |
|
634 // Verify that this is the BB5 partition table |
|
635 if( memcompare( (TUint8*)&(partitionTable->iId[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 ) |
|
636 { |
|
637 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Nokia partition structure found")); |
|
638 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->iId )); |
|
639 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->iSector_size, partitionTable->iSector_size)); |
|
640 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->iMajor_ver)); |
|
641 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->iMinor_ver)); |
|
642 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->iPartition_amount)); |
|
643 |
|
644 TUint8 partitionType = 0; |
|
645 // Check Supported Version is present |
|
646 if (partitionTable->iMajor_ver <= BGAHSMMCPTN_PI_VER_MAJOR) |
|
647 { |
|
648 for( TUint8 index = 0; (index < partitionTable->iPartition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ ) |
|
649 { |
|
650 if (partitionTable->iMinor_ver >= BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR) |
|
651 partitionType = partitionTable->iPartitions[index].iPartition_type; |
|
652 else |
|
653 partitionType = partitionTable->iPartitions[index].iPartition_id; |
|
654 |
|
655 // FAT/PMM/CPS/SWAP/CORE/ROFS/CRASH |
|
656 if( (partitionTable->iPartitions[index].iSize > 0) && |
|
657 ( PartitionIsFAT(partitionType) || |
|
658 PartitionIsFAT32(partitionType) || |
|
659 (KPartitionTypeSymbianCrashLog == partitionType) || |
|
660 (KPartitionTypePartitionMagic == partitionType) || //CPS/PMM |
|
661 (KPartitionTypeRofs == partitionType) || |
|
662 (KPartitionTypeEmpty == partitionType) || |
|
663 (KPartitionTypeROM == partitionType) || |
|
664 (KPartitionTypePagedData == partitionType) ) ) |
|
665 { |
|
666 iPartitionInfo->iEntry[partitionCount].iPartitionType = partitionType; |
|
667 iPartitionAttributes[partitionCount] = partitionTable->iPartitions[index].iPartition_attributes; |
|
668 static_cast<DMmcMediaDriverFlash *>(iDriver)->SetEMmcPartitionMapping(partitionCount, iSelectedPartition); |
|
669 // ROM/ROFS partitions have a BB5 checksum header that must be offset for the Symbian OS. |
|
670 const TUint32 KStartOffset = ((KPartitionTypeROM == partitionType) || (KPartitionTypeRofs == partitionType) || (KPartitionTypeEmpty == partitionType)) ? KBB5HeaderSizeInSectors : 0; |
|
671 |
|
672 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = ((Int64) partitionTable->iPartitions[index].iStart_sector + KStartOffset) << KDiskSectorShift; |
|
673 iPartitionInfo->iEntry[partitionCount].iPartitionLen = ((Int64) partitionTable->iPartitions[index].iSize - KStartOffset) << KDiskSectorShift; |
|
674 |
|
675 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount)); |
|
676 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount)); |
|
677 __KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector )); |
|
678 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift))); |
|
679 __KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize )); |
|
680 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift)); |
|
681 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType)); |
|
682 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount])); |
|
683 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionMapping.: 0x%x", static_cast<DMmcMediaDriverFlash *>(iDriver)->GetEMmcPartitionMapping(partitionCount))); |
|
684 __KTRACE_OPT(KPBUSDRV, Kern::Printf(" ")); |
|
685 |
|
686 partitionCount++; |
|
687 r = KErrNone; |
|
688 } |
|
689 } |
|
690 } |
|
691 |
|
692 if(partitionCount > iPartitionInfo->iPartitionCount) |
|
693 { |
|
694 __KTRACE_OPT(KPBUSDRV, Kern::Printf("DBB5PartitionInfo: New BB5 partitions found")); |
|
695 #ifdef __DEBUG_CHECK_PARTITION_ |
|
696 r = CheckPartitionBoundaries(iPartitionInfo->iPartitionCount,partitionCount); |
|
697 if (r == KErrNone) |
|
698 #endif // __DEBUG_CHECK_PARTITION_ |
|
699 { |
|
700 //Update master partition count |
|
701 iPartitionInfo->iPartitionCount = partitionCount; |
|
702 iPartitionInfo->iMediaSizeInBytes = iCard->DeviceSize64(); |
|
703 } |
|
704 } |
|
705 } |
|
706 |
|
707 __KTRACE_OPT(KPBUSDRV, Kern::Printf("< DBB5PartitionInfo: DecodeBB5PartitionInfo(%d)",r)); |
|
708 return r; |
|
709 } |
|
710 |
|
711 |
|
712 TInt DBB5PartitionInfo::DecodeTOCPartitionInfo() |
|
713 // |
|
714 // Decode partition info that was read into internal buffer |
|
715 // |
|
716 { |
|
717 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">DBB5PartitionInfo: DecodeTOCPartitionInfo(%d)",iPartitionInfo->iPartitionCount)); |
|
718 TInt partitionCount = iPartitionInfo->iPartitionCount; |
400 TInt r = KErrNone; |
719 TInt r = KErrNone; |
401 |
720 |
402 if (iCheckTOC) |
721 // Try utilising the TOC (Table Of Contents) partitioning scheme |
403 { |
722 const TText8* KRofsNames[KNoOfROFSPartitions] = { KTocRofs1Generic, |
404 // Try utilising the TOC (Table Of Contents) partitioning scheme |
723 KTocRofs2Generic, |
405 const TText8* KRofsNames[KNoOfROFSPartitions] = { KTocRofs1Generic, |
724 KTocRofs3Generic, |
406 KTocRofs2Generic, |
725 KTocRofs4Generic, |
407 KTocRofs3Generic, |
726 KTocRofs5Generic, |
408 KTocRofs4Generic, |
727 KTocRofs6Generic, |
409 KTocRofs5Generic, |
728 }; |
410 KTocRofs6Generic, |
729 |
411 }; |
730 STocItem item; |
412 |
731 memcpy( iTocPtr, &iIntBuf[0], sizeof(Toc)); |
413 STocItem item; |
732 |
414 iTocPtr = reinterpret_cast<Toc*>(&iIntBuf[0]); |
733 #ifdef __PRINT_RAW_ENTRIES |
415 iTocPtr->iTocStartSector = KTocStartSector; |
734 Kern::Printf("TOC Entry"); |
|
735 for (TUint i = 0; i < 512; i+=8) |
|
736 { |
|
737 Kern::Printf("%02x %02x %02x %02x %02x %02x %02x %02x", iIntBuf[i],iIntBuf[i+1],iIntBuf[i+2],iIntBuf[i+3],iIntBuf[i+4],iIntBuf[i+5],iIntBuf[i+6],iIntBuf[i+7]); |
|
738 } |
|
739 #endif |
|
740 |
|
741 iTocPtr->iTocStartSector = KTocStartSector; |
416 |
742 |
417 // USER Drive - Only 1 |
743 // USER Drive - Only 1 |
418 r = iTocPtr->GetItemByName(KTocUserName, item); |
744 r = iTocPtr->GetItemByName(KTocUserName, item); |
419 if (KErrNone == r) |
745 if (KErrNone == r) |
|
746 { |
|
747 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
748 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeFAT16; |
|
749 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64)item.iStart; |
|
750 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64)item.iSize; |
|
751 iPartitionAttributes[partitionCount] = 0; // No Additional Attributes required. |
|
752 partitionCount++; |
|
753 } |
|
754 |
|
755 // ROM Drive |
|
756 r = iTocPtr->GetItemByName(KTocRomGeneric, item); |
|
757 if (KErrNone == r) |
|
758 { |
|
759 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%x Size = 0x%x", item.iFileName, item.iStart, item.iSize)); |
|
760 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeROM; |
|
761 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); |
|
762 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); |
|
763 partitionCount++; |
|
764 } |
|
765 |
|
766 // ROFS |
|
767 for (TUint i = 0; i < KNoOfROFSPartitions; i++) |
|
768 { |
|
769 /* Search ROFSn item */ |
|
770 r = iTocPtr->GetItemByName(KRofsNames[i], item); |
|
771 if (r == KErrNone) |
420 { |
772 { |
421 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
773 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
422 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeFAT16; |
774 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeRofs; |
423 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64)item.iStart; |
|
424 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64)item.iSize; |
|
425 iPartitionAttributes[partitionCount] = 0; // No Additional Attributes required. |
|
426 partitionCount++; |
|
427 } |
|
428 |
|
429 // ROM Drive |
|
430 r = iTocPtr->GetItemByName(KTocRomGeneric, item); |
|
431 if (KErrNone == r) |
|
432 { |
|
433 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%x Size = 0x%x", item.iFileName, item.iStart, item.iSize)); |
|
434 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeROM; |
|
435 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); |
775 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); |
436 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); |
776 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); |
437 partitionCount++; |
777 partitionCount++; |
438 } |
778 } |
439 |
779 } |
440 // ROFS |
780 |
441 for (TUint i = 0; i < KNoOfROFSPartitions; i++) |
781 // CPS Drive - Only 1 |
|
782 r = iTocPtr->GetItemByName(KTocCps, item); |
|
783 if (KErrNone == r) |
|
784 { |
|
785 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
786 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePartitionMagic; |
|
787 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
|
788 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
|
789 partitionCount++; |
|
790 } |
|
791 |
|
792 // CRASH Drive - Only 1 |
|
793 r = iTocPtr->GetItemByName(KTocCrashLog, item); |
|
794 if (KErrNone == r) |
|
795 { |
|
796 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
797 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeSymbianCrashLog; |
|
798 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
|
799 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
|
800 partitionCount++; |
|
801 } |
|
802 |
|
803 // SWAP Partition - Only 1 |
|
804 r = iTocPtr->GetItemByName(KTocSwap, item); |
|
805 if (KErrNone == r) |
|
806 { |
|
807 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
|
808 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePagedData; |
|
809 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
|
810 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
|
811 partitionCount++; |
|
812 } |
|
813 |
|
814 #ifdef __DEBUG_PARTITIONS_ |
|
815 for (TInt i = 0; i<partitionCount; i++) |
|
816 { |
|
817 Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[i].iPartitionType); |
|
818 Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[i].iPartitionBaseAddr >> KDiskSectorShift)); |
|
819 Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionLen, iPartitionInfo->iEntry[i].iPartitionLen >> KDiskSectorShift); |
|
820 Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[i]); |
|
821 Kern::Printf(" "); |
|
822 } |
|
823 #endif //__DEBUG_PARTITIONS_ |
|
824 |
|
825 if(partitionCount > iPartitionInfo->iPartitionCount) |
|
826 { |
|
827 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: New supported partitions found!")); |
|
828 #ifdef __DEBUG_CHECK_PARTITION_ |
|
829 r = CheckPartitionBoundaries(iPartitionInfo->iPartitionCount,partitionCount); |
|
830 if (r == KErrNone) |
|
831 #endif // __DEBUG_CHECK_PARTITION_ |
442 { |
832 { |
443 /* Search ROFSn item */ |
833 //Update master partition count |
444 r = iTocPtr->GetItemByName(KRofsNames[i], item); |
834 iPartitionInfo->iPartitionCount = partitionCount; |
445 if (r == KErrNone) |
835 iPartitionInfo->iMediaSizeInBytes = iCard->DeviceSize64(); |
446 { |
836 r = KErrNone; |
447 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
837 } |
448 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeRofs; |
838 } |
449 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart + (KBB5HeaderSizeInSectors << KDiskSectorShift); |
839 else |
450 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize - (KBB5HeaderSizeInSectors << KDiskSectorShift); |
840 { |
451 partitionCount++; |
841 __KTRACE_OPT(KPBUSDRV, Kern::Printf("<DBB5PartitionInfo: No New Partitions found - TOC")); |
452 } |
842 r = KErrNotFound; |
453 } |
843 } |
454 |
844 |
455 // CPS Drive - Only 1 |
845 __KTRACE_OPT(KPBUSDRV, Kern::Printf("<DBB5PartitionInfo: DecodeTOCPartitionInfo(%d)",r)); |
456 r = iTocPtr->GetItemByName(KTocCps, item); |
846 return r; |
457 if (KErrNone == r) |
847 } |
|
848 |
|
849 |
|
850 // Version Info Support |
|
851 TInt DBB5PartitionInfo::HalFunction(TInt aFunction, TAny* a1, TAny* /*a2*/) |
|
852 { |
|
853 TInt ret = KErrGeneral; |
|
854 |
|
855 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">DBB5PartitionInfo::HalFunction")); |
|
856 |
|
857 if (aFunction == EGetVersionInfoItems) |
|
858 { |
|
859 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">DBB5PartitionInfo::EGetVersionInfoItems %d Version Headers",iVersionInfoItems )); |
|
860 kumemput32(a1, &iVersionInfoItems, sizeof(TUint32)); |
|
861 ret = KErrNone; |
|
862 } |
|
863 else if (aFunction == EGetVersionInfo) |
|
864 { |
|
865 __KTRACE_OPT(KPBUSDRV, Kern::Printf(">DBB5PartitionInfo::EGetVersionInfo")); |
|
866 kumemput32(a1, &iVersionInfo[0], sizeof(TVersionInfoItem)*iVersionInfoItems); |
|
867 ret = KErrNone; |
|
868 } |
|
869 |
|
870 __KTRACE_OPT(KPBUSDRV, Kern::Printf("<DBB5PartitionInfo::HalFunction")); |
|
871 |
|
872 return ret; |
|
873 } |
|
874 |
|
875 // returns KErrNotfound if reached the end of the toc |
|
876 TInt DBB5PartitionInfo::ReadTOCVersionInfo(TUint32& aOffset) |
|
877 { |
|
878 TInt r = KErrNotFound; |
|
879 for (; iTocCount < KMaxNbrOfTocItems; iTocCount++ ) |
|
880 { |
|
881 __KTRACE_OPT(KPBUSDRV, Kern::Printf("ReadTOCVersionInfo: Find next usable TOC entry (%d)",iTocCount)); |
|
882 // Iterate through the partition info table looking for valid partition headers |
|
883 if ( iTocPtr->iTOC[iTocCount].iStart == KEndOfToc ) |
458 { |
884 { |
459 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
885 __KTRACE_OPT(KPBUSDRV, Kern::Printf("ReadTOCVersionInfo: End of the TOC")); |
460 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePartitionMagic; |
886 break; |
461 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
887 } |
462 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
888 else if ( iTocPtr->iTOC[iTocCount].iStart & 0x80000000 ) |
463 partitionCount++; |
889 { |
|
890 __KTRACE_OPT(KPBUSDRV, Kern::Printf("ReadTOCVersionInfo: Image has negative offset")); |
|
891 continue; |
|
892 } |
|
893 else if ( iTocPtr->iTOC[iTocCount].iSize <= 1024 ) |
|
894 { |
|
895 __KTRACE_OPT(KPBUSDRV, Kern::Printf("ReadTOCVersionInfo: entry is less than 2 sectors in size")); |
|
896 continue; |
464 } |
897 } |
465 |
898 |
466 // CRASH Drive - Only 1 |
899 r = KErrNone; |
467 r = iTocPtr->GetItemByName(KTocCrashLog, item); |
900 break; |
468 if (KErrNone == r) |
901 } |
469 { |
902 |
470 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
903 if (r == KErrNone) |
471 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypeSymbianCrashLog; |
904 { |
472 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
905 aOffset = ((iTocPtr->iTOC[iTocCount].iStart) >> KSectorShift) + (iTocPtr->iTocStartSector); |
473 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
906 } |
474 partitionCount++; |
907 |
475 } |
908 return r; |
476 |
909 } |
477 // SWAP Partition - Only 1 |
910 |
478 r = iTocPtr->GetItemByName(KTocSwap, item); |
911 void DBB5PartitionInfo::DecodeVersionInfo() |
479 if (KErrNone == r) |
912 { |
480 { |
913 __KTRACE_OPT(KPBUSDRV,Kern::Printf(">Decode Version Info (%d)",iVersionInfoItems)); |
481 __KTRACE_OPT(KPBUSDRV, Kern::Printf("[MD : ] (%11s) in TOC found : Start addr = 0x%X Size = 0x%X", item.iFileName, item.iStart, item.iSize)); |
914 |
482 iPartitionInfo->iEntry[partitionCount].iPartitionType = KPartitionTypePagedData; |
915 #ifdef __PRINT_RAW_ENTRIES |
483 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) item.iStart; |
916 Kern::Printf("Version Info:"); |
484 iPartitionInfo->iEntry[partitionCount].iPartitionLen = (Int64) item.iSize; |
917 for (TUint i = 0; i < 1024; i+=8) |
485 partitionCount++; |
918 { |
486 } |
919 Kern::Printf("%02x %02x %02x %02x %02x %02x %02x %02x", iIntBuf[i],iIntBuf[i+1],iIntBuf[i+2],iIntBuf[i+3],iIntBuf[i+4],iIntBuf[i+5],iIntBuf[i+6],iIntBuf[i+7]); |
487 |
920 } |
488 #ifdef __DEBUG_PARTITIONS_ |
921 #endif |
489 for (TInt i = 0; i<partitionCount; i++) |
922 |
490 { |
923 // check BB5 common header and image header |
491 Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[i].iPartitionType); |
924 if ( *(TUint32*)&iIntBuf[0] == KBB5_CommonHeaderMagic || |
492 Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[i].iPartitionBaseAddr >> KDiskSectorShift)); |
925 *(TUint32*)&iIntBuf[KImageHeaderOffset] == KImageHeaderMagic ) |
493 Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[i].iPartitionLen, iPartitionInfo->iEntry[i].iPartitionLen >> KDiskSectorShift); |
926 { |
494 Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[i]); |
927 // pick up required info from TOC |
495 Kern::Printf(" "); |
928 TVersionInfoItem *vinfo = (TVersionInfoItem *)&iVersionInfo[iVersionInfoItems]; |
496 } |
929 vinfo->iSectionMaxSize = iTocPtr->iTOC[iTocCount].iSize; |
497 #endif //__DEBUG_PARTITIONS_ |
930 memcpy( &vinfo->iSectionName[0], &iTocPtr->iTOC[iTocCount].iFileName[0], KMaxSectionNameLen); |
498 |
931 |
499 r = KErrNone; |
932 // pick up required info from image header |
500 iCheckTOC = EFalse; |
933 TImageHeader *himage = (TImageHeader *)&iIntBuf[KImageHeaderOffset]; |
501 } |
934 vinfo->iImageCompressedSize = himage->iImageCompressedSize; |
502 else |
935 vinfo->iImageSize = himage->iImageSize; |
503 { |
936 memcpy( &vinfo->iVersion[0], &himage->iVersion[0], KMaxVersionInfoLen); |
504 // Try utilising the BB5 partitioning scheme |
937 |
505 BGAHSMMCPTN_PI_STR *partitionTable = (BGAHSMMCPTN_PI_STR*)(&iIntBuf[0]); |
938 |
506 |
939 __KTRACE_OPT(KPBUSDRV,Kern::Printf("Section Name (%11s)",vinfo->iSectionName)); |
507 // Verify that this is the Nokia partition table |
940 __KTRACE_OPT(KPBUSDRV,Kern::Printf("Section size (%d)",vinfo->iSectionMaxSize)); |
508 if( memcompare( (TUint8*)&(partitionTable->iId[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 ) |
941 __KTRACE_OPT(KPBUSDRV,Kern::Printf("Compressed Size %d", vinfo->iImageCompressedSize)); |
509 { |
942 __KTRACE_OPT(KPBUSDRV,Kern::Printf("Image Size %d", vinfo->iImageSize)); |
510 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Nokia partition structure found")); |
943 __KTRACE_OPT(KPBUSDRV,Kern::Printf("VersionInfo (%11s)",vinfo->iVersion)); |
511 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->iId )); |
944 |
512 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->iSector_size, partitionTable->iSector_size)); |
945 iVersionInfoItems++; |
513 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->iMajor_ver)); |
946 } |
514 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->iMinor_ver)); |
947 |
515 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->iPartition_amount)); |
948 __KTRACE_OPT(KPBUSDRV,Kern::Printf("<Decode Version Info (%d)",iVersionInfoItems)); |
516 |
949 return; |
517 TUint8 partitionType = 0; |
950 } |
518 // Check Supported Version is present |
|
519 if (partitionTable->iMajor_ver <= BGAHSMMCPTN_PI_VER_MAJOR) |
|
520 { |
|
521 for( TUint8 index = 0; (index < partitionTable->iPartition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ ) |
|
522 { |
|
523 if (partitionTable->iMinor_ver >= BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR) |
|
524 partitionType = partitionTable->iPartitions[index].iPartition_type; |
|
525 else |
|
526 partitionType = partitionTable->iPartitions[index].iPartition_id; |
|
527 |
|
528 // FAT/PMM/CPS/SWAP/CORE/ROFS/CRASH |
|
529 if( (partitionTable->iPartitions[index].iSize > 0) && |
|
530 ( PartitionIsFAT(partitionType) || |
|
531 PartitionIsFAT32(partitionType) || |
|
532 (KPartitionTypeSymbianCrashLog == partitionType) || |
|
533 (KPartitionTypePartitionMagic == partitionType) || //CPS/PMM |
|
534 (KPartitionTypeRofs == partitionType) || |
|
535 (KPartitionTypeEmpty == partitionType) || |
|
536 (KPartitionTypeROM == partitionType) || |
|
537 (KPartitionTypePagedData == partitionType) ) ) |
|
538 { |
|
539 iPartitionInfo->iEntry[partitionCount].iPartitionType = partitionType; |
|
540 iPartitionAttributes[partitionCount] = partitionTable->iPartitions[index].iPartition_attributes; |
|
541 static_cast<DMmcMediaDriverFlash *>(iDriver)->SetEMmcPartitionMapping(partitionCount, iSelectedPartition); |
|
542 // ROM/ROFS partitions have a BB5 checksum header that must be offset for the Symbian OS. |
|
543 const TUint32 KStartOffset = ((KPartitionTypeROM == partitionType) || (KPartitionTypeRofs == partitionType) || (KPartitionTypeEmpty == partitionType)) ? KBB5HeaderSizeInSectors : 0; |
|
544 |
|
545 iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = ((Int64) partitionTable->iPartitions[index].iStart_sector + KStartOffset) << KDiskSectorShift; |
|
546 iPartitionInfo->iEntry[partitionCount].iPartitionLen = ((Int64) partitionTable->iPartitions[index].iSize - KStartOffset) << KDiskSectorShift; |
|
547 |
|
548 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount)); |
|
549 __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount)); |
|
550 __KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector )); |
|
551 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift))); |
|
552 __KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize )); |
|
553 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift)); |
|
554 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType)); |
|
555 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount])); |
|
556 __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionMapping.: 0x%x", static_cast<DMmcMediaDriverFlash *>(iDriver)->GetEMmcPartitionMapping(partitionCount))); |
|
557 __KTRACE_OPT(KPBUSDRV, Kern::Printf(" ")); |
|
558 |
|
559 partitionCount++; |
|
560 } |
|
561 } |
|
562 } |
|
563 } |
|
564 else |
|
565 { |
|
566 __KTRACE_OPT(KPBUSDRV, Kern::Printf("BGAHSMMC signature not found - try TOC layout")); |
|
567 iCheckTOC = ETrue; |
|
568 |
|
569 TInt r = ReadPartition(KTocStartSector); |
|
570 return r; |
|
571 } |
|
572 } |
|
573 |
|
574 |
|
575 // Validate partition address boundaries |
|
576 if(partitionCount == 0) |
|
577 { |
|
578 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: No supported partitions found!")); |
|
579 // No Supported partitions found on this physical partition |
|
580 return KErrNone; |
|
581 } |
|
582 |
|
583 #ifdef __DEBUG_CHECK_PARTITION_ |
|
584 // Validate partition address boundaries |
|
585 TUint32 eMmcPartitionSizeInSectors = 0; |
|
586 if(r == KErrNone) |
|
587 { |
|
588 // At least one entry for a supported partition found |
|
589 r = GetPartitionSizeInSectors(iSelectedPartition, eMmcPartitionSizeInSectors); |
|
590 |
|
591 if(r != KErrNone) |
|
592 { |
|
593 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Could not retrieve size for eMMC partition 0x%02X", iSelectedPartition)); |
|
594 r = KErrCorrupt; |
|
595 } |
|
596 } |
|
597 |
|
598 if(r == KErrNone) |
|
599 { |
|
600 TUint64 eMmcPartitionSize = eMmcPartitionSizeInSectors * KSectorSize; |
|
601 |
|
602 TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1]; |
|
603 |
|
604 // Check that the eMmcPartition address space boundary is not exceeded by the last partition |
|
605 if(part.iPartitionBaseAddr + part.iPartitionLen > eMmcPartitionSize) |
|
606 { |
|
607 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Partition #%d exceeds eMmc address space", partitionCount)); |
|
608 r = KErrCorrupt; |
|
609 } |
|
610 } |
|
611 |
|
612 if(r == KErrNone) |
|
613 { |
|
614 // Go through all BB5 partition entries on this eMMC partition and check boundaries |
|
615 for(TInt i = partitionCount - 1; i > iPartitionInfo->iPartitionCount; i--) |
|
616 { |
|
617 const TPartitionEntry& curr = iPartitionInfo->iEntry[i]; |
|
618 TPartitionEntry& prev = iPartitionInfo->iEntry[i-1]; |
|
619 |
|
620 // Check if partitions overlap |
|
621 if(curr.iPartitionBaseAddr < (prev.iPartitionBaseAddr + prev.iPartitionLen)) |
|
622 { |
|
623 __KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Overlapping partitions - check #%d", i)); |
|
624 r = KErrCorrupt; |
|
625 } |
|
626 } |
|
627 } |
|
628 #endif // _DEBUG_CHECK_PARTITION_ |
|
629 |
|
630 if(r == KErrNone) |
|
631 { |
|
632 iPartitionInfo->iPartitionCount = partitionCount; |
|
633 iPartitionInfo->iMediaSizeInBytes = iCard->DeviceSize64(); |
|
634 } |
|
635 |
|
636 __KTRACE_OPT(KPBUSDRV, Kern::Printf("<Mmc:PartitionInfo (C:%d)", partitionCount)); |
|
637 return r; |
|
638 } |
|
639 |
951 |
640 |
952 |
641 // End - DBB5PartitionInfo |
953 // End - DBB5PartitionInfo |
642 |
954 |
643 |
955 |