sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\include\memmodel\epoc\platform.h sl@0: // Public header file for device drivers sl@0: // sl@0: // WARNING: This file contains some APIs which are internal and are subject sl@0: // to change without notice. Such APIs should therefore not be used sl@0: // outside the Kernel and Hardware Services package. sl@0: // sl@0: sl@0: #ifndef __M32STD_H__ sl@0: #define __M32STD_H__ sl@0: #include sl@0: #include sl@0: #ifdef __EPOC32__ sl@0: #include sl@0: #else sl@0: class TRomHeader; sl@0: class TRomImageHeader; sl@0: class TRomEntry; sl@0: #endif sl@0: // sl@0: sl@0: /******************************************** sl@0: * Hardware chunk abstraction sl@0: ********************************************/ sl@0: sl@0: /** sl@0: The list of memory types (aka cache attributes) in Kernel on ARMv6K, ARMv7 and later platforms. sl@0: Types 0-3 can be used on all platforms. Types 4-7 can be used only on the platforms with memory type remapping. sl@0: @see TMappingAttributes2 sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: enum TMemoryType sl@0: { sl@0: EMemAttStronglyOrdered = 0, /**< Strongly Ordered memory.*/ sl@0: EMemAttDevice = 1, /**< Device memory.*/ sl@0: EMemAttNormalUncached = 2, /**< Uncached Normal memory. Writes may combine.*/ sl@0: EMemAttNormalCached = 3, /**< Fully cached (Write-Back, Read/Write Allocate, Normal memory).*/ sl@0: EMemAttKernelInternal4 = 4, /**< @internalComponent. Not to be used by device drivers.*/ sl@0: EMemAttPlatformSpecific5= 5, /**< Defined by Baseport - H/W independent.*/ sl@0: EMemAttPlatformSpecific6= 6, /**< Defined by Baseport - H/W specific - see ARM core's document for the details.*/ sl@0: EMemAttPlatformSpecific7= 7 /**< Defined by Baseport - H/W independent.*/ sl@0: }; sl@0: sl@0: const TUint KMemoryTypeShift = 3; /**< @internalComponent. The number of bits in a TMemoryType value.*/ sl@0: const TUint KMemoryTypeMask = (1<0 Shareable memory sl@0: To ensure future compatibility, use the value <0 except when absolutely neccessary. sl@0: Default argument value is -1. sl@0: @param aParity Parity error attribute of the mapping: sl@0: <0 Default value for the platform (which is off on all platforms so far). sl@0: ==0 Parity error doesn't generate external abort. sl@0: >0 Parity error generates external abort. sl@0: To ensure future compatibility, use the value <0 except when absolutely neccessary. sl@0: Default argument value is -1. sl@0: sl@0: @see TMemoryType sl@0: */ sl@0: IMPORT_C TMappingAttributes2(TMemoryType aType , sl@0: TBool aUserAccess , sl@0: TBool aWritable , sl@0: TBool aExecutable = EFalse, sl@0: TInt aShared = -1, sl@0: TInt aParity = -1); sl@0: sl@0: TMappingAttributes2(TUint aMapAttr);/**< @internalComponent*/ sl@0: TMemoryType Type(); /**< @internalComponent @return Type of the memory (aka cache attributes).*/ sl@0: TBool UserAccess(); /**< @internalComponent @return True if memory can be accessed from user code.*/ sl@0: TBool Writable(); /**< @internalComponent @return True if memory can be written into, false if this is reaad only memory.*/ sl@0: TBool Executable(); /**< @internalComponent @return True if memory can contain code and data, false if it can only contain data.*/ sl@0: TBool Shared(); /**< @internalComponent @return True if memory is shared, false if not.*/ sl@0: TBool Parity(); /**< @internalComponent @return True if parity error generates external abort, false if not.*/ sl@0: TBool ObjectType2();/**< @internalComponent @return True if the object is TMappingAttributes2, false if it is TMappingAttributes bitmask.*/ sl@0: private: sl@0: static void Panic(TInt aPanic); /**< @internalComponent*/ sl@0: private: sl@0: TUint32 iAttributes; /**< @internalComponent*/ sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: inline TBool ComparePermissions(TInt aActual, TInt aRequired) sl@0: { sl@0: return ((aActual&EMapAttrReadMask)>=(aRequired&EMapAttrReadMask)) && sl@0: ((aActual&EMapAttrWriteMask)>=(aRequired&EMapAttrWriteMask)) && sl@0: ((aActual&EMapAttrExecMask)>=(aRequired&EMapAttrExecMask)); sl@0: } sl@0: sl@0: sl@0: /** Hardware Chunk class sl@0: Class representing a global mapping of I/O or global memory buffers sl@0: sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class DPlatChunkHw : public DObject sl@0: { sl@0: public: sl@0: IMPORT_C static TInt New(DPlatChunkHw*& aChunk, TPhysAddr anAddr, TInt aSize, TUint aAttribs); sl@0: inline TLinAddr LinearAddress() {return iLinAddr;} sl@0: inline TPhysAddr PhysicalAddress() {return iPhysAddr;} sl@0: public: sl@0: /** @internalComponent */ sl@0: static TInt DoNew(DPlatChunkHw*& aChunk, TPhysAddr anAddr, TInt aSize, TUint aAttribs); sl@0: public: sl@0: TPhysAddr iPhysAddr; /**< @internalComponent */ sl@0: TLinAddr iLinAddr; /**< @internalComponent */ sl@0: TInt iSize; /**< @internalComponent */ sl@0: TUint iAttribs; /**< @internalComponent */ // mapping attributes sl@0: }; sl@0: sl@0: /******************************************** sl@0: * Exports from layer 2 or below of the kernel sl@0: * which are not available to layer 1 sl@0: ********************************************/ sl@0: sl@0: /** sl@0: Specifies the operation performed by the TRamZoneCallback function. sl@0: @see TRamZoneCallback sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: enum TRamZoneOp sl@0: { sl@0: /** Informs the variant that a specified RAM zone is not currently sl@0: being used and therefore it may be possible to save power by not refreshing sl@0: this zone or, if the rest of the its RAM IC's zones are also empty, powering sl@0: down the RAM IC. sl@0: sl@0: The TRamZoneCallback parameter aParam1 is the ID of the zone. sl@0: The TRamZoneCallback parameter aParam2 is a pointer to const array of TUints sl@0: that are the bit masks of the zones' power status. sl@0: */ sl@0: ERamZoneOp_PowerDown=0, sl@0: sl@0: /** Informs the variant that a specified RAM zone is now required for use sl@0: and therefore it must be ready. sl@0: The variant should ensure the zone is refreshed, if required, and that the sl@0: RAM IC is powered and fully initialised. sl@0: sl@0: The TRamZoneCallback parameter aParam1 is the ID of the zone. sl@0: The TRamZoneCallback parameter aParam2 is a pointer to const array of TUints sl@0: that are the bit masks of the zones' power status. sl@0: */ sl@0: ERamZoneOp_PowerUp=1, sl@0: sl@0: /** Operation that informs the variant of the RAM zones that have been used sl@0: during the initial stages of the boot process. Any RAM zones that are not sl@0: in use may be powered down or not refreshed to save power. sl@0: This will be the first operation requested of the variant and it is only sl@0: issued once. sl@0: sl@0: The TRamZoneCallback parameter aParam1 is unused by this operation. sl@0: The TRamZoneCallback parameter aParam2 is a pointer to const array of TUints sl@0: that are the bit masks of the zones' power status. sl@0: */ sl@0: ERamZoneOp_Init=2, sl@0: }; sl@0: sl@0: sl@0: /** sl@0: Call back function that is invoked by the kernel when its RAM allocator determines sl@0: that an operation can be performed on a particular RAM zone. sl@0: sl@0: @publishedPartner sl@0: @released sl@0: sl@0: @param aOp Type of operation to perform; a value of TRamZoneOp sl@0: @param aParam1 A value whose use is defined by the TRamZoneOp to be performed sl@0: @param aParam2 A value whose use is defined by the TRamZoneOp to be performed sl@0: The data pointed to by aParam2 is const and therefore should not be modified sl@0: sl@0: @return KErrNone if successful, otherwise one of the system wide error codes sl@0: sl@0: @see TRamZoneOp sl@0: */ sl@0: typedef TInt (*TRamZoneCallback) (TRamZoneOp aOp, TAny* aParam1, const TAny* aParam2); sl@0: sl@0: /** sl@0: Holds the number of each page type within a RAM zone. sl@0: sl@0: @see Epoc::GetRamZonePageCount() sl@0: sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: struct SRamZonePageCount sl@0: { sl@0: TUint iFreePages; /**< The number of free pages in the RAM zone*/ sl@0: TUint iUnknownPages; /**< The number of unknown pages in the RAM zone*/ sl@0: TUint iFixedPages; /**< The number of fixed pages in the RAM zone*/ sl@0: TUint iMovablePages; /**< The number of movable pages in the RAM zone*/ sl@0: TUint iDiscardablePages;/**< The number of discardable pages in the RAM zone*/ sl@0: TUint iReserved[4]; /**<@internalComponent reserved for internal use only*/ sl@0: }; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class Epoc sl@0: { sl@0: public: sl@0: /** sl@0: The types of RAM defragmentation operations. sl@0: @internalComponent sl@0: */ sl@0: enum TRamDefragOp sl@0: { sl@0: ERamDefrag_DefragRam, sl@0: ERamDefrag_EmptyRamZone, sl@0: ERamDefrag_ClaimRamZone, sl@0: }; sl@0: sl@0: /** sl@0: The type of page to move with Epoc::MovePhysicalPage(). sl@0: @internalComponent sl@0: */ sl@0: enum TRamDefragPageToMove sl@0: { sl@0: /** sl@0: Move the physical page aOld. sl@0: */ sl@0: ERamDefragPage_Physical, sl@0: /** sl@0: Move the page table page that maps the linear address in the sl@0: current thread at aOld. sl@0: */ sl@0: ERamDefragPage_PageTable, sl@0: /** sl@0: Move the page table info page of the page table that maps the linear sl@0: address in the current thread at aOld. sl@0: */ sl@0: ERamDefragPage_PageTableInfo, sl@0: }; sl@0: sl@0: sl@0: IMPORT_C static void SetMonitorEntryPoint(TDfcFn aFunction); /**< @internalComponent */ sl@0: IMPORT_C static void SetMonitorExceptionHandler(TLinAddr aHandler); /**< @internalComponent */ sl@0: IMPORT_C static TAny* ExceptionInfo(); /**< @internalComponent */ sl@0: IMPORT_C static const TRomHeader& RomHeader(); sl@0: IMPORT_C static TInt AllocShadowPage(TLinAddr aRomAddr); sl@0: IMPORT_C static TInt CopyToShadowMemory(TLinAddr aDest, TLinAddr aSrc, TUint32 aLength); sl@0: IMPORT_C static TInt FreeShadowPage(TLinAddr aRomAddr); sl@0: IMPORT_C static TInt FreezeShadowPage(TLinAddr aRomAddr); sl@0: IMPORT_C static TInt AllocPhysicalRam(TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign=0); sl@0: IMPORT_C static TInt ZoneAllocPhysicalRam(TUint aZoneId, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign=0); sl@0: IMPORT_C static TInt ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign=0); sl@0: IMPORT_C static TInt AllocPhysicalRam(TInt aNumPages, TPhysAddr* aPageList); sl@0: IMPORT_C static TInt ZoneAllocPhysicalRam(TUint aZoneId, TInt aNumPages, TPhysAddr* aPageList); sl@0: IMPORT_C static TInt ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages, TPhysAddr* aPageList); sl@0: IMPORT_C static TInt FreePhysicalRam(TPhysAddr aPhysAddr, TInt aSize); sl@0: IMPORT_C static TInt FreePhysicalRam(TInt aNumPages, TPhysAddr* aPageList); sl@0: IMPORT_C static TInt ClaimPhysicalRam(TPhysAddr aPhysAddr, TInt aSize); sl@0: IMPORT_C static TPhysAddr LinearToPhysical(TLinAddr aLinAddr); sl@0: IMPORT_C static void RomProcessInfo(TProcessCreateInfo& aInfo, const TRomImageHeader& aRomImageHeader); /**< @internalComponent */ sl@0: #ifdef BTRACE_KERNEL_MEMORY sl@0: static TInt DriverAllocdPhysRam; // the number of bytes allocated by Epoc::AllocPhysicalRam and Epoc::FreePhysicalRam sl@0: static TInt KernelMiscPages; // the number of bytes of 'miscelaneous' kernel memory allocated sl@0: #endif sl@0: IMPORT_C static TInt MovePhysicalPage(TPhysAddr aOld, TPhysAddr& aNew, TRamDefragPageToMove aPageToMove=ERamDefragPage_Physical); /**< @internalComponent */ sl@0: IMPORT_C static TInt SetRamZoneConfig(const SRamZone* aZones, TRamZoneCallback aCallback); sl@0: IMPORT_C static TInt GetRamZonePageCount(TUint aId, SRamZonePageCount& aPageData); sl@0: IMPORT_C static TInt ModifyRamZoneFlags(TUint aId, TUint aClearMask, TUint aSetMask); sl@0: }; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class DebugSupport sl@0: { sl@0: public: sl@0: sl@0: /** Bitmask values representing different breakpoint types. */ sl@0: enum TType sl@0: { sl@0: EBreakpointGlobal = 1<<0, /**< Breakpoint appears in all processes */ sl@0: EBreakpointLocal = 1<<1, /**< Breakpoint appears in the specified process only. */ sl@0: }; sl@0: sl@0: IMPORT_C static TInt InitialiseCodeModifier(TUint& aCapabilities, TInt aMinBreakpoints); sl@0: IMPORT_C static void CloseCodeModifier(); sl@0: IMPORT_C static TInt ModifyCode(DThread* aThread, TLinAddr aAddress, TInt aSize, TUint aValue, TUint aType); sl@0: IMPORT_C static TInt RestoreCode(DThread* aThread, TLinAddr aAddress); sl@0: sl@0: /** sl@0: @internalTechnology sl@0: @prototype sl@0: */ sl@0: IMPORT_C static void TerminateProcess(DProcess* aProcess, const TInt aReason); sl@0: sl@0: }; sl@0: sl@0: #ifdef __DEBUGGER_SUPPORT__ sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CodeModifier : public DBase sl@0: { sl@0: public: sl@0: sl@0: /** Values for panic values in category 'CodeModifier'. */ sl@0: enum TPanic sl@0: { sl@0: EPanicNotInitialised = 0, sl@0: EPanicInvalidSizeOrAlignment = 1, sl@0: }; sl@0: sl@0: /** Defines the type/size of the breakpoint - see TBreakpoint::iSize*/ sl@0: enum TBrkType sl@0: { sl@0: EEmpty =0, //The slot is unused sl@0: EByte =1, //Jazelle breakpoint sl@0: EHalfword =2, //Thumb breakpoint sl@0: EWord =4 //ARM breakpoint sl@0: }; sl@0: sl@0: TInt static CreateAndInitialise(TInt aMinBreakpoints); sl@0: ~CodeModifier(); sl@0: void Close(); sl@0: TInt Modify(DThread* aThread, TLinAddr aAddress, TInt aSize, TUint aValue); sl@0: TInt Restore(DThread* aThread, TLinAddr aAddress); sl@0: static void CodeSegRemoved(DCodeSeg* aCodeSeg, DProcess* aProcess); sl@0: static DMutex& Mutex() {return *Kern::CodeSegLock();} sl@0: static void Fault(TPanic aPanic); sl@0: sl@0: private: sl@0: sl@0: /**Desribes a breakpoint slot in the pool*/ sl@0: struct TBreakpoint sl@0: { sl@0: TUint iProcessId; //Id of the process associated to this breakpoint. sl@0: TUint iAddress; //The virtual address of the breakpoint sl@0: TUint32 iOldValue; //Will hold the original content of iAddress sl@0: TInt16 iSize; //Could be one of TBrkType. 0 means empty/unused, otherwise it indicates the size of the breakpoint in bytes. sl@0: TInt16 iPageIndex; //If iSize!=0 identifies corresponding shadowed page, or -1 if it is non-XIP page. sl@0: }; sl@0: sl@0: /** Desribes a page slot in the pool. Used for pages that are shadowed or need to be locked (for demand paging). */ sl@0: struct TPageInfo sl@0: { sl@0: TLinAddr iAddress; //Base address of the page. sl@0: TInt32 iCounter; //The number of breakpoints associated with this page. 0 indicates empty slot. sl@0: TBool iWasShadowed; //True if the page had been already shadowed before the first breakpoint was applied, sl@0: //false otherwise. If true, it won't be un-shadowed after all breakpoints are removed. sl@0: #ifdef __DEMAND_PAGING__ sl@0: /// If set, points to the deamnd paging lock object used to lock this page. Only applies to sl@0: /// RAM-loaded code. sl@0: DDemandPagingLock* iPagingLock; sl@0: #endif sl@0: }; sl@0: private: sl@0: TBreakpoint* FindBreakpoint(DThread* aThread, TLinAddr aAddress, TInt aSize, TBool& aOverlap); sl@0: TBreakpoint* FindEmptyBrk(); sl@0: TInt FindEmptyPageInfo(); sl@0: TInt FindPageInfo(TLinAddr aAddress); sl@0: TInt IsRom(TLinAddr aAddress); sl@0: TInt WriteCode(TLinAddr aAddress, TInt aSize, TUint aValue, void* aOldValue); sl@0: DProcess* Process(TUint aProcessId); sl@0: TInt SafeWriteCode(DProcess* aProcess, TLinAddr aAddress, TInt aSize, TUint aValue, void* aOldValue); sl@0: void RestorePage(TInt aPageIndex); sl@0: void DoCodeSegRemoved(DCodeSeg* aCodeSeg, DProcess* aProcess); sl@0: sl@0: private: sl@0: TInt iPoolSize; sl@0: TBreakpoint* iBreakpoints; //Breakpoint pool with iPoolSize slots sl@0: TPageInfo* iPages; //The pool of the shadowed/locked pages with iPoolSize slots sl@0: TUint iPageSize; sl@0: TUint iPageMask; sl@0: }; sl@0: sl@0: GLREF_D CodeModifier* TheCodeModifier; sl@0: #endif //__DEBUGGER_SUPPORT__ sl@0: sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: inline const TRomEntry &RomEntry(TLinAddr anAddr) sl@0: {return(*((const TRomEntry *)anAddr));} sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: inline const TRomImageHeader& RomImageHeader(TLinAddr anAddr) sl@0: {return(*((const TRomImageHeader*)anAddr));} sl@0: sl@0: /** sl@0: TRamDefragRequest is intended to be used by device drivers to request that RAM defragmentation sl@0: operations are performed. sl@0: sl@0: All RAM defragmentation operations can be invoked synchronously or asynchronously. sl@0: The asynchronous RAM defragmentation operations can use either a TDfc or a NFastSemaphore sl@0: to signal to the caller that the operation has completed. sl@0: sl@0: @see TDfc sl@0: @see NFastSemaphore sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class TRamDefragRequest : protected TAsyncRequest sl@0: { sl@0: public: sl@0: IMPORT_C TRamDefragRequest(); sl@0: IMPORT_C TInt DefragRam(TInt aPriority, TInt aMaxPages=0); sl@0: IMPORT_C TInt DefragRam(NFastSemaphore* aSem, TInt aPriority, TInt aMaxPages=0); sl@0: IMPORT_C TInt DefragRam(TDfc* aDfc, TInt aPriority, TInt aMaxPages=0); sl@0: IMPORT_C TInt EmptyRamZone(TUint aId, TInt aPriority); sl@0: IMPORT_C TInt EmptyRamZone(TUint aId, NFastSemaphore* aSem, TInt aPriority); sl@0: IMPORT_C TInt EmptyRamZone(TUint aId, TDfc* aDfc, TInt aPriority); sl@0: IMPORT_C TInt ClaimRamZone(TUint aId, TPhysAddr& aPhysAddr, TInt aPriority); sl@0: IMPORT_C TInt ClaimRamZone(TUint aId, TPhysAddr& aPhysAddr, NFastSemaphore* aSem, TInt aPriority); sl@0: IMPORT_C TInt ClaimRamZone(TUint aId, TPhysAddr& aPhysAddr, TDfc* aDfc, TInt aPriority); sl@0: IMPORT_C TInt Result(); sl@0: IMPORT_C void Cancel(); sl@0: sl@0: /** sl@0: Values that can be specified to control which thread priority sl@0: the RAM defragmentation operations are run with. sl@0: */ sl@0: enum TPrioritySpecial sl@0: { sl@0: /** sl@0: The RAM defragmentation operation will use the same thread priority as sl@0: that of the caller. sl@0: */ sl@0: KInheritPriority = -1, sl@0: }; sl@0: sl@0: private: sl@0: void SetupPriority(TInt aPriority); sl@0: sl@0: private: sl@0: Epoc::TRamDefragOp iOp; sl@0: TUint iId; sl@0: TUint iMaxPages; sl@0: TInt iThreadPriority; sl@0: TPhysAddr* iPhysAddr; sl@0: TInt iSpare[6]; sl@0: sl@0: public: sl@0: friend class Defrag; sl@0: }; sl@0: sl@0: sl@0: #endif sl@0: