/*************************************************************************/ /*!
|
@File
|
@Title Device specific initialisation routines
|
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
|
@Description Device specific MMU initialisation
|
@License Dual MIT/GPLv2
|
|
The contents of this file are subject to the MIT license as set out below.
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
of this software and associated documentation files (the "Software"), to deal
|
in the Software without restriction, including without limitation the rights
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
copies of the Software, and to permit persons to whom the Software is
|
furnished to do so, subject to the following conditions:
|
|
The above copyright notice and this permission notice shall be included in
|
all copies or substantial portions of the Software.
|
|
Alternatively, the contents of this file may be used under the terms of
|
the GNU General Public License Version 2 ("GPL") in which case the provisions
|
of GPL are applicable instead of those above.
|
|
If you wish to allow use of your version of this file only under the terms of
|
GPL, and not to allow others to use your version of this file under the terms
|
of the MIT license, indicate your decision by deleting the provisions above
|
and replace them with the notice and other provisions required by GPL as set
|
out in the file called "GPL-COPYING" included in this distribution. If you do
|
not delete the provisions above, a recipient may use your version of this file
|
under the terms of either the MIT license or GPL.
|
|
This License is also included in this distribution in the file called
|
"MIT-COPYING".
|
|
EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
|
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
*/ /**************************************************************************/
|
#include "rgxmmuinit.h"
|
#include "rgxmmudefs_km.h"
|
|
#include "device.h"
|
#include "img_types.h"
|
#include "mmu_common.h"
|
#include "pdump_mmu.h"
|
|
#include "pvr_debug.h"
|
#include "pvrsrv_error.h"
|
#include "rgx_memallocflags.h"
|
#include "rgx_heaps.h"
|
#include "pdump_km.h"
|
|
|
/* useful macros */
|
/* units represented in a bitfield */
|
#define UNITS_IN_BITFIELD(Mask, Shift) ((Mask >> Shift) + 1)
|
|
|
/*
|
* Bits of PT, PD and PC not involving addresses
|
*/
|
|
#define RGX_MMUCTRL_PTE_PROTMASK (RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN | \
|
RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_EN | \
|
RGX_MMUCTRL_PT_DATA_PM_SRC_EN | \
|
RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN | \
|
RGX_MMUCTRL_PT_DATA_CC_EN | \
|
RGX_MMUCTRL_PT_DATA_READ_ONLY_EN | \
|
RGX_MMUCTRL_PT_DATA_VALID_EN)
|
|
#define RGX_MMUCTRL_PDE_PROTMASK (RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_EN | \
|
~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK | \
|
RGX_MMUCTRL_PD_DATA_VALID_EN)
|
|
#define RGX_MMUCTRL_PCE_PROTMASK (RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_EN | \
|
RGX_MMUCTRL_PC_DATA_VALID_EN)
|
|
|
|
static MMU_PxE_CONFIG sRGXMMUPCEConfig;
|
static MMU_DEVVADDR_CONFIG sRGXMMUTopLevelDevVAddrConfig;
|
|
|
/*
|
*
|
* Configuration for heaps with 4kB Data-Page size
|
*
|
*/
|
|
static MMU_PxE_CONFIG sRGXMMUPDEConfig_4KBDP;
|
static MMU_PxE_CONFIG sRGXMMUPTEConfig_4KBDP;
|
static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_4KBDP;
|
static MMU_PAGESIZECONFIG gsPageSizeConfig4KB;
|
|
|
/*
|
*
|
* Configuration for heaps with 16kB Data-Page size
|
*
|
*/
|
|
static MMU_PxE_CONFIG sRGXMMUPDEConfig_16KBDP;
|
static MMU_PxE_CONFIG sRGXMMUPTEConfig_16KBDP;
|
static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_16KBDP;
|
static MMU_PAGESIZECONFIG gsPageSizeConfig16KB;
|
|
|
/*
|
*
|
* Configuration for heaps with 64kB Data-Page size
|
*
|
*/
|
|
static MMU_PxE_CONFIG sRGXMMUPDEConfig_64KBDP;
|
static MMU_PxE_CONFIG sRGXMMUPTEConfig_64KBDP;
|
static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_64KBDP;
|
static MMU_PAGESIZECONFIG gsPageSizeConfig64KB;
|
|
|
/*
|
*
|
* Configuration for heaps with 256kB Data-Page size
|
*
|
*/
|
|
static MMU_PxE_CONFIG sRGXMMUPDEConfig_256KBDP;
|
static MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP;
|
static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_256KBDP;
|
static MMU_PAGESIZECONFIG gsPageSizeConfig256KB;
|
|
|
/*
|
*
|
* Configuration for heaps with 1MB Data-Page size
|
*
|
*/
|
|
static MMU_PxE_CONFIG sRGXMMUPDEConfig_1MBDP;
|
static MMU_PxE_CONFIG sRGXMMUPTEConfig_1MBDP;
|
static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_1MBDP;
|
static MMU_PAGESIZECONFIG gsPageSizeConfig1MB;
|
|
|
/*
|
*
|
* Configuration for heaps with 2MB Data-Page size
|
*
|
*/
|
|
static MMU_PxE_CONFIG sRGXMMUPDEConfig_2MBDP;
|
static MMU_PxE_CONFIG sRGXMMUPTEConfig_2MBDP;
|
static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_2MBDP;
|
static MMU_PAGESIZECONFIG gsPageSizeConfig2MB;
|
|
|
/* Forward declaration of protection bits derivation functions, for
|
the following structure */
|
static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize);
|
static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags);
|
static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize);
|
static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags);
|
static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize);
|
static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags);
|
|
static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize,
|
const MMU_PxE_CONFIG **ppsMMUPDEConfig,
|
const MMU_PxE_CONFIG **ppsMMUPTEConfig,
|
const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig,
|
IMG_HANDLE *phPriv);
|
|
static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv);
|
|
static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize);
|
static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize);
|
|
static MMU_DEVICEATTRIBS sRGXMMUDeviceAttributes;
|
|
PVRSRV_ERROR RGXMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode)
|
{
|
/* Setup of Px Entries:
|
*
|
*
|
* PAGE TABLE (8 Byte):
|
*
|
* | 62 | 61...40 | 39...12 (varies) | 11...6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
* | PM/Meta protect | VP Page (39:18) | Physical Page | VP Page (17:12) | Entry Pending | PM src | SLC Bypass Ctrl | Cache Coherency | Read Only | Valid |
|
*
|
*
|
* PAGE DIRECTORY (8 Byte):
|
*
|
* | 40 | 39...5 (varies) | 4 | 3...1 | 0 |
|
* | Entry Pending | Page Table base address | (reserved) | Page Size | Valid |
|
*
|
*
|
* PAGE CATALOGUE (4 Byte):
|
*
|
* | 31...4 | 3...2 | 1 | 0 |
|
* | Page Directory base address | (reserved) | Entry Pending | Valid |
|
*
|
*/
|
|
|
/* Example how to get the PD address from a PC entry.
|
* The procedure is the same for PD and PT entries to retrieve PT and Page addresses:
|
*
|
* 1) sRGXMMUPCEConfig.uiAddrMask applied to PC entry with '&':
|
* | 31...4 | 3...2 | 1 | 0 |
|
* | PD Addr | 0 | 0 | 0 |
|
*
|
* 2) sRGXMMUPCEConfig.uiAddrShift applied with '>>':
|
* | 27...0 |
|
* | PD Addr |
|
*
|
* 3) sRGXMMUPCEConfig.uiAddrLog2Align applied with '<<':
|
* | 39...0 |
|
* | PD Addr |
|
*
|
*/
|
|
|
sRGXMMUDeviceAttributes.pszMMUPxPDumpMemSpaceName =
|
PhysHeapPDumpMemspaceName(psDeviceNode->apsPhysHeap[PVRSRV_DEVICE_PHYS_HEAP_GPU_LOCAL]);
|
|
/*
|
* Setup sRGXMMUPCEConfig
|
*/
|
sRGXMMUPCEConfig.uiBytesPerEntry = 4; /* 32 bit entries */
|
sRGXMMUPCEConfig.uiAddrMask = 0xfffffff0; /* Mask to get significant address bits of PC entry i.e. the address of the PD */
|
|
sRGXMMUPCEConfig.uiAddrShift = 4; /* Shift this many bits to get PD address */
|
sRGXMMUPCEConfig.uiAddrLog2Align = 12; /* Alignment of PD physical addresses. */
|
|
sRGXMMUPCEConfig.uiProtMask = RGX_MMUCTRL_PCE_PROTMASK; /* Mask to get the status bits (pending | valid)*/
|
sRGXMMUPCEConfig.uiProtShift = 0; /* Shift this many bits to get the statis bits */
|
|
sRGXMMUPCEConfig.uiValidEnMask = RGX_MMUCTRL_PC_DATA_VALID_EN; /* Mask to get entry valid bit of the PC */
|
sRGXMMUPCEConfig.uiValidEnShift = RGX_MMUCTRL_PC_DATA_VALID_SHIFT; /* Shift this many bits to get entry valid bit */
|
|
/*
|
* Setup sRGXMMUTopLevelDevVAddrConfig
|
*/
|
sRGXMMUTopLevelDevVAddrConfig.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; /* Mask to get PC index applied to a 40 bit virt. device address */
|
sRGXMMUTopLevelDevVAddrConfig.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT; /* Shift a 40 bit virt. device address by this amount to get the PC index */
|
sRGXMMUTopLevelDevVAddrConfig.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUTopLevelDevVAddrConfig.uiPCIndexMask,
|
sRGXMMUTopLevelDevVAddrConfig.uiPCIndexShift));
|
|
sRGXMMUTopLevelDevVAddrConfig.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; /* Mask to get PD index applied to a 40 bit virt. device address */
|
sRGXMMUTopLevelDevVAddrConfig.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT; /* Shift a 40 bit virt. device address by this amount to get the PD index */
|
sRGXMMUTopLevelDevVAddrConfig.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUTopLevelDevVAddrConfig.uiPDIndexMask,
|
sRGXMMUTopLevelDevVAddrConfig.uiPDIndexShift));
|
|
/*
|
*
|
* Configuration for heaps with 4kB Data-Page size
|
*
|
*/
|
|
/*
|
* Setup sRGXMMUPDEConfig_4KBDP
|
*/
|
sRGXMMUPDEConfig_4KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPDEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
|
sRGXMMUPDEConfig_4KBDP.uiAddrShift = 12;
|
sRGXMMUPDEConfig_4KBDP.uiAddrLog2Align = 12;
|
|
sRGXMMUPDEConfig_4KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
|
sRGXMMUPDEConfig_4KBDP.uiVarCtrlShift = 1;
|
|
sRGXMMUPDEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
|
sRGXMMUPDEConfig_4KBDP.uiProtShift = 0;
|
|
sRGXMMUPDEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
|
sRGXMMUPDEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUPTEConfig_4KBDP
|
*/
|
sRGXMMUPTEConfig_4KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPTEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffff000);
|
sRGXMMUPTEConfig_4KBDP.uiAddrShift = 12;
|
sRGXMMUPTEConfig_4KBDP.uiAddrLog2Align = 12; /* Alignment of the physical addresses of the pages NOT PTs */
|
|
sRGXMMUPTEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
|
sRGXMMUPTEConfig_4KBDP.uiProtShift = 0;
|
|
sRGXMMUPTEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
|
sRGXMMUPTEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUDevVAddrConfig_4KBDP
|
*/
|
sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexMask,
|
sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexShift));
|
|
sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexMask,
|
sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexShift));
|
|
sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexMask = ~RGX_MMUCTRL_VADDR_PT_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexShift = RGX_MMUCTRL_VADDR_PT_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_4KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexMask,
|
sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexShift));
|
|
sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000000fff);
|
sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetShift = 0;
|
sRGXMMUDevVAddrConfig_4KBDP.uiOffsetInBytes = 0;
|
|
/*
|
* Setup gsPageSizeConfig4KB
|
*/
|
gsPageSizeConfig4KB.psPDEConfig = &sRGXMMUPDEConfig_4KBDP;
|
gsPageSizeConfig4KB.psPTEConfig = &sRGXMMUPTEConfig_4KBDP;
|
gsPageSizeConfig4KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_4KBDP;
|
gsPageSizeConfig4KB.uiRefCount = 0;
|
gsPageSizeConfig4KB.uiMaxRefCount = 0;
|
|
|
/*
|
*
|
* Configuration for heaps with 16kB Data-Page size
|
*
|
*/
|
|
/*
|
* Setup sRGXMMUPDEConfig_16KBDP
|
*/
|
sRGXMMUPDEConfig_16KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPDEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
|
sRGXMMUPDEConfig_16KBDP.uiAddrShift = 10;
|
sRGXMMUPDEConfig_16KBDP.uiAddrLog2Align = 10;
|
|
sRGXMMUPDEConfig_16KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
|
sRGXMMUPDEConfig_16KBDP.uiVarCtrlShift = 1;
|
|
sRGXMMUPDEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
|
sRGXMMUPDEConfig_16KBDP.uiProtShift = 0;
|
|
sRGXMMUPDEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
|
sRGXMMUPDEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUPTEConfig_16KBDP
|
*/
|
sRGXMMUPTEConfig_16KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPTEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xffffffc000);
|
sRGXMMUPTEConfig_16KBDP.uiAddrShift = 14;
|
sRGXMMUPTEConfig_16KBDP.uiAddrLog2Align = 14;
|
|
sRGXMMUPTEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
|
sRGXMMUPTEConfig_16KBDP.uiProtShift = 0;
|
|
sRGXMMUPTEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
|
sRGXMMUPTEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUDevVAddrConfig_16KBDP
|
*/
|
sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexMask,
|
sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexMask,
|
sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001fc000);
|
sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexShift = 14;
|
sRGXMMUDevVAddrConfig_16KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexMask,
|
sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexShift));
|
|
sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000003fff);
|
sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetShift = 0;
|
sRGXMMUDevVAddrConfig_16KBDP.uiOffsetInBytes = 0;
|
|
/*
|
* Setup gsPageSizeConfig16KB
|
*/
|
gsPageSizeConfig16KB.psPDEConfig = &sRGXMMUPDEConfig_16KBDP;
|
gsPageSizeConfig16KB.psPTEConfig = &sRGXMMUPTEConfig_16KBDP;
|
gsPageSizeConfig16KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_16KBDP;
|
gsPageSizeConfig16KB.uiRefCount = 0;
|
gsPageSizeConfig16KB.uiMaxRefCount = 0;
|
|
|
/*
|
*
|
* Configuration for heaps with 64kB Data-Page size
|
*
|
*/
|
|
/*
|
* Setup sRGXMMUPDEConfig_64KBDP
|
*/
|
sRGXMMUPDEConfig_64KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPDEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
|
sRGXMMUPDEConfig_64KBDP.uiAddrShift = 8;
|
sRGXMMUPDEConfig_64KBDP.uiAddrLog2Align = 8;
|
|
sRGXMMUPDEConfig_64KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
|
sRGXMMUPDEConfig_64KBDP.uiVarCtrlShift = 1;
|
|
sRGXMMUPDEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
|
sRGXMMUPDEConfig_64KBDP.uiProtShift = 0;
|
|
sRGXMMUPDEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
|
sRGXMMUPDEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUPTEConfig_64KBDP
|
*/
|
sRGXMMUPTEConfig_64KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPTEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xffffff0000);
|
sRGXMMUPTEConfig_64KBDP.uiAddrShift =16;
|
sRGXMMUPTEConfig_64KBDP.uiAddrLog2Align = 16;
|
|
sRGXMMUPTEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
|
sRGXMMUPTEConfig_64KBDP.uiProtShift = 0;
|
|
sRGXMMUPTEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
|
sRGXMMUPTEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUDevVAddrConfig_64KBDP
|
*/
|
sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexMask,
|
sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexMask,
|
sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001f0000);
|
sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexShift = 16;
|
sRGXMMUDevVAddrConfig_64KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexMask,
|
sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000000ffff);
|
sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetShift = 0;
|
sRGXMMUDevVAddrConfig_64KBDP.uiOffsetInBytes = 0;
|
|
/*
|
* Setup gsPageSizeConfig64KB
|
*/
|
gsPageSizeConfig64KB.psPDEConfig = &sRGXMMUPDEConfig_64KBDP;
|
gsPageSizeConfig64KB.psPTEConfig = &sRGXMMUPTEConfig_64KBDP;
|
gsPageSizeConfig64KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_64KBDP;
|
gsPageSizeConfig64KB.uiRefCount = 0;
|
gsPageSizeConfig64KB.uiMaxRefCount = 0;
|
|
|
/*
|
*
|
* Configuration for heaps with 256kB Data-Page size
|
*
|
*/
|
|
/*
|
* Setup sRGXMMUPDEConfig_256KBDP
|
*/
|
sRGXMMUPDEConfig_256KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPDEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
|
sRGXMMUPDEConfig_256KBDP.uiAddrShift = 6;
|
sRGXMMUPDEConfig_256KBDP.uiAddrLog2Align = 6;
|
|
sRGXMMUPDEConfig_256KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
|
sRGXMMUPDEConfig_256KBDP.uiVarCtrlShift = 1;
|
|
sRGXMMUPDEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
|
sRGXMMUPDEConfig_256KBDP.uiProtShift = 0;
|
|
sRGXMMUPDEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
|
sRGXMMUPDEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
|
|
/*
|
* Setup MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP
|
*/
|
sRGXMMUPTEConfig_256KBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPTEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffc0000);
|
sRGXMMUPTEConfig_256KBDP.uiAddrShift = 18;
|
sRGXMMUPTEConfig_256KBDP.uiAddrLog2Align = 18;
|
|
sRGXMMUPTEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
|
sRGXMMUPTEConfig_256KBDP.uiProtShift = 0;
|
|
sRGXMMUPTEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
|
sRGXMMUPTEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUDevVAddrConfig_256KBDP
|
*/
|
sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexMask,
|
sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexMask,
|
sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001c0000);
|
sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexShift = 18;
|
sRGXMMUDevVAddrConfig_256KBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexMask,
|
sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000003ffff);
|
sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetShift = 0;
|
sRGXMMUDevVAddrConfig_256KBDP.uiOffsetInBytes = 0;
|
|
/*
|
* Setup gsPageSizeConfig256KB
|
*/
|
gsPageSizeConfig256KB.psPDEConfig = &sRGXMMUPDEConfig_256KBDP;
|
gsPageSizeConfig256KB.psPTEConfig = &sRGXMMUPTEConfig_256KBDP;
|
gsPageSizeConfig256KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_256KBDP;
|
gsPageSizeConfig256KB.uiRefCount = 0;
|
gsPageSizeConfig256KB.uiMaxRefCount = 0;
|
|
/*
|
* Setup sRGXMMUPDEConfig_1MBDP
|
*/
|
sRGXMMUPDEConfig_1MBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPDEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
|
sRGXMMUPDEConfig_1MBDP.uiAddrShift = 4;
|
sRGXMMUPDEConfig_1MBDP.uiAddrLog2Align = 4;
|
|
sRGXMMUPDEConfig_1MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
|
sRGXMMUPDEConfig_1MBDP.uiVarCtrlShift = 1;
|
|
sRGXMMUPDEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
|
sRGXMMUPDEConfig_1MBDP.uiProtShift = 0;
|
|
sRGXMMUPDEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
|
sRGXMMUPDEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUPTEConfig_1MBDP
|
*/
|
sRGXMMUPTEConfig_1MBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPTEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffff00000);
|
sRGXMMUPTEConfig_1MBDP.uiAddrShift = 20;
|
sRGXMMUPTEConfig_1MBDP.uiAddrLog2Align = 20;
|
|
sRGXMMUPTEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
|
sRGXMMUPTEConfig_1MBDP.uiProtShift = 0;
|
|
sRGXMMUPTEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
|
sRGXMMUPTEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUDevVAddrConfig_1MBDP
|
*/
|
sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexMask,
|
sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexMask,
|
sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000100000);
|
sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexShift = 20;
|
sRGXMMUDevVAddrConfig_1MBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexMask,
|
sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00000fffff);
|
sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetShift = 0;
|
sRGXMMUDevVAddrConfig_1MBDP.uiOffsetInBytes = 0;
|
|
/*
|
* Setup gsPageSizeConfig1MB
|
*/
|
gsPageSizeConfig1MB.psPDEConfig = &sRGXMMUPDEConfig_1MBDP;
|
gsPageSizeConfig1MB.psPTEConfig = &sRGXMMUPTEConfig_1MBDP;
|
gsPageSizeConfig1MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_1MBDP;
|
gsPageSizeConfig1MB.uiRefCount = 0;
|
gsPageSizeConfig1MB.uiMaxRefCount = 0;
|
|
/*
|
* Setup sRGXMMUPDEConfig_2MBDP
|
*/
|
sRGXMMUPDEConfig_2MBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPDEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
|
sRGXMMUPDEConfig_2MBDP.uiAddrShift = 4;
|
sRGXMMUPDEConfig_2MBDP.uiAddrLog2Align = 4;
|
|
sRGXMMUPDEConfig_2MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
|
sRGXMMUPDEConfig_2MBDP.uiVarCtrlShift = 1;
|
|
sRGXMMUPDEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
|
sRGXMMUPDEConfig_2MBDP.uiProtShift = 0;
|
|
sRGXMMUPDEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
|
sRGXMMUPDEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUPTEConfig_2MBDP
|
*/
|
sRGXMMUPTEConfig_2MBDP.uiBytesPerEntry = 8;
|
|
sRGXMMUPTEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xffffe00000);
|
sRGXMMUPTEConfig_2MBDP.uiAddrShift = 21;
|
sRGXMMUPTEConfig_2MBDP.uiAddrLog2Align = 21;
|
|
sRGXMMUPTEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
|
sRGXMMUPTEConfig_2MBDP.uiProtShift = 0;
|
|
sRGXMMUPTEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
|
sRGXMMUPTEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
|
|
/*
|
* Setup sRGXMMUDevVAddrConfig_2MBDP
|
*/
|
sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPC = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexMask,
|
sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
|
sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
|
sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPD = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexMask,
|
sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000000000);
|
sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexShift = 21;
|
sRGXMMUDevVAddrConfig_2MBDP.uiNumEntriesPT = TRUNCATE_64BITS_TO_32BITS(UNITS_IN_BITFIELD(sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexMask,
|
sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexShift));
|
|
|
sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00001fffff);
|
sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetShift = 0;
|
sRGXMMUDevVAddrConfig_2MBDP.uiOffsetInBytes = 0;
|
|
/*
|
* Setup gsPageSizeConfig2MB
|
*/
|
gsPageSizeConfig2MB.psPDEConfig = &sRGXMMUPDEConfig_2MBDP;
|
gsPageSizeConfig2MB.psPTEConfig = &sRGXMMUPTEConfig_2MBDP;
|
gsPageSizeConfig2MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_2MBDP;
|
gsPageSizeConfig2MB.uiRefCount = 0;
|
gsPageSizeConfig2MB.uiMaxRefCount = 0;
|
|
/*
|
* Setup sRGXMMUDeviceAttributes
|
*/
|
sRGXMMUDeviceAttributes.eMMUType = PDUMP_MMU_TYPE_VARPAGE_40BIT;
|
sRGXMMUDeviceAttributes.eTopLevel = MMU_LEVEL_3;
|
sRGXMMUDeviceAttributes.ui32BaseAlign = RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT;
|
sRGXMMUDeviceAttributes.psBaseConfig = &sRGXMMUPCEConfig;
|
sRGXMMUDeviceAttributes.psTopLevelDevVAddrConfig = &sRGXMMUTopLevelDevVAddrConfig;
|
|
/* Functions for deriving page table/dir/cat protection bits */
|
sRGXMMUDeviceAttributes.pfnDerivePCEProt8 = RGXDerivePCEProt8;
|
sRGXMMUDeviceAttributes.pfnDerivePCEProt4 = RGXDerivePCEProt4;
|
sRGXMMUDeviceAttributes.pfnDerivePDEProt8 = RGXDerivePDEProt8;
|
sRGXMMUDeviceAttributes.pfnDerivePDEProt4 = RGXDerivePDEProt4;
|
sRGXMMUDeviceAttributes.pfnDerivePTEProt8 = RGXDerivePTEProt8;
|
sRGXMMUDeviceAttributes.pfnDerivePTEProt4 = RGXDerivePTEProt4;
|
|
/* Functions for establishing configurations for PDE/PTE/DEVVADDR
|
on per-heap basis */
|
sRGXMMUDeviceAttributes.pfnGetPageSizeConfiguration = RGXGetPageSizeConfigCB;
|
sRGXMMUDeviceAttributes.pfnPutPageSizeConfiguration = RGXPutPageSizeConfigCB;
|
|
sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE4 = RGXGetPageSizeFromPDE4;
|
sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE8 = RGXGetPageSizeFromPDE8;
|
|
psDeviceNode->psMMUDevAttrs = &sRGXMMUDeviceAttributes;
|
|
return PVRSRV_OK;
|
}
|
|
PVRSRV_ERROR RGXMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode)
|
{
|
PVRSRV_ERROR eError;
|
|
eError = PVRSRV_OK;
|
|
#if defined(PDUMP)
|
psDeviceNode->pfnMMUGetContextID = NULL;
|
#endif
|
|
psDeviceNode->psMMUDevAttrs = NULL;
|
|
#if defined(DEBUG)
|
PVR_DPF((PVR_DBG_MESSAGE, "Variable Page Size Heap Stats:"));
|
PVR_DPF((PVR_DBG_MESSAGE, "Max 4K page heaps: %d",
|
gsPageSizeConfig4KB.uiMaxRefCount));
|
PVR_DPF((PVR_DBG_VERBOSE, "Current 4K page heaps (should be 0): %d",
|
gsPageSizeConfig4KB.uiRefCount));
|
PVR_DPF((PVR_DBG_MESSAGE, "Max 16K page heaps: %d",
|
gsPageSizeConfig16KB.uiMaxRefCount));
|
PVR_DPF((PVR_DBG_VERBOSE, "Current 16K page heaps (should be 0): %d",
|
gsPageSizeConfig16KB.uiRefCount));
|
PVR_DPF((PVR_DBG_MESSAGE, "Max 64K page heaps: %d",
|
gsPageSizeConfig64KB.uiMaxRefCount));
|
PVR_DPF((PVR_DBG_VERBOSE, "Current 64K page heaps (should be 0): %d",
|
gsPageSizeConfig64KB.uiRefCount));
|
PVR_DPF((PVR_DBG_MESSAGE, "Max 256K page heaps: %d",
|
gsPageSizeConfig256KB.uiMaxRefCount));
|
PVR_DPF((PVR_DBG_VERBOSE, "Current 256K page heaps (should be 0): %d",
|
gsPageSizeConfig256KB.uiRefCount));
|
PVR_DPF((PVR_DBG_MESSAGE, "Max 1M page heaps: %d",
|
gsPageSizeConfig1MB.uiMaxRefCount));
|
PVR_DPF((PVR_DBG_VERBOSE, "Current 1M page heaps (should be 0): %d",
|
gsPageSizeConfig1MB.uiRefCount));
|
PVR_DPF((PVR_DBG_MESSAGE, "Max 2M page heaps: %d",
|
gsPageSizeConfig2MB.uiMaxRefCount));
|
PVR_DPF((PVR_DBG_VERBOSE, "Current 2M page heaps (should be 0): %d",
|
gsPageSizeConfig2MB.uiRefCount));
|
#endif
|
if (gsPageSizeConfig4KB.uiRefCount > 0 ||
|
gsPageSizeConfig16KB.uiRefCount > 0 ||
|
gsPageSizeConfig64KB.uiRefCount > 0 ||
|
gsPageSizeConfig256KB.uiRefCount > 0 ||
|
gsPageSizeConfig1MB.uiRefCount > 0 ||
|
gsPageSizeConfig2MB.uiRefCount > 0
|
)
|
{
|
PVR_DPF((PVR_DBG_ERROR, "RGXMMUInit_Unregister: Unbalanced MMU API Usage (Internal error)"));
|
}
|
|
return eError;
|
}
|
|
/*************************************************************************/ /*!
|
@Function RGXDerivePCEProt4
|
@Description calculate the PCE protection flags based on a 4 byte entry
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags)
|
{
|
return (uiProtFlags & MMU_PROTFLAGS_INVALID)?0:RGX_MMUCTRL_PC_DATA_VALID_EN;
|
}
|
|
|
/*************************************************************************/ /*!
|
@Function RGXDerivePCEProt8
|
@Description calculate the PCE protection flags based on an 8 byte entry
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize)
|
{
|
PVR_UNREFERENCED_PARAMETER(uiProtFlags);
|
PVR_UNREFERENCED_PARAMETER(uiLog2DataPageSize);
|
|
PVR_DPF((PVR_DBG_ERROR, "8-byte PCE not supported on this device"));
|
return 0;
|
}
|
|
|
/*************************************************************************/ /*!
|
@Function RGXDerivePDEProt4
|
@Description derive the PDE protection flags based on a 4 byte entry
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags)
|
{
|
PVR_UNREFERENCED_PARAMETER(uiProtFlags);
|
PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device"));
|
return 0;
|
}
|
|
|
/*************************************************************************/ /*!
|
@Function RGXDerivePDEProt8
|
@Description derive the PDE protection flags based on an 8 byte entry
|
|
@Input uiLog2DataPageSize The log2 of the required page size.
|
E.g, for 4KiB pages, this parameter must be 12.
|
For 2MiB pages, it must be set to 21.
|
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize)
|
{
|
IMG_UINT64 ret_value = 0; // 0 means invalid
|
|
if (! (uiProtFlags & MMU_PROTFLAGS_INVALID)) // if not invalid
|
{
|
switch (uiLog2DataPageSize)
|
{
|
case RGX_HEAP_4KB_PAGE_SHIFT:
|
ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB;
|
break;
|
case RGX_HEAP_16KB_PAGE_SHIFT:
|
ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB;
|
break;
|
case RGX_HEAP_64KB_PAGE_SHIFT:
|
ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB;
|
break;
|
case RGX_HEAP_256KB_PAGE_SHIFT:
|
ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB;
|
break;
|
case RGX_HEAP_1MB_PAGE_SHIFT:
|
ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB;
|
break;
|
case RGX_HEAP_2MB_PAGE_SHIFT:
|
ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB;
|
break;
|
default:
|
PVR_DPF((PVR_DBG_ERROR,
|
"%s:%d: in function<%s>: Invalid parameter log2_page_size. Expected {12, 14, 16, 18, 20, 21}. Got [%u]",
|
__FILE__, __LINE__, __FUNCTION__, uiLog2DataPageSize));
|
}
|
}
|
return ret_value;
|
}
|
|
|
/*************************************************************************/ /*!
|
@Function RGXDerivePTEProt4
|
@Description calculate the PTE protection flags based on a 4 byte entry
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags)
|
{
|
PVR_UNREFERENCED_PARAMETER(uiProtFlags);
|
PVR_DPF((PVR_DBG_ERROR, "4-byte PTE not supported on this device"));
|
|
return 0;
|
}
|
|
/*************************************************************************/ /*!
|
@Function RGXDerivePTEProt8
|
@Description calculate the PTE protection flags based on an 8 byte entry
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 uiLog2DataPageSize)
|
{
|
IMG_UINT64 ui64MMUFlags=0;
|
|
PVR_UNREFERENCED_PARAMETER(uiLog2DataPageSize);
|
|
if(((MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE) & uiProtFlags) == (MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE))
|
{
|
/* read/write */
|
}
|
else if(MMU_PROTFLAGS_READABLE & uiProtFlags)
|
{
|
/* read only */
|
ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_READ_ONLY_EN;
|
}
|
else if(MMU_PROTFLAGS_WRITEABLE & uiProtFlags)
|
{
|
/* write only */
|
PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt8: write-only is not possible on this device"));
|
}
|
else if ((MMU_PROTFLAGS_INVALID & uiProtFlags) == 0)
|
{
|
PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt8: neither read nor write specified..."));
|
}
|
|
/* cache coherency */
|
if(MMU_PROTFLAGS_CACHE_COHERENT & uiProtFlags)
|
{
|
ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_CC_EN;
|
}
|
|
/* cache setup */
|
if ((MMU_PROTFLAGS_CACHED & uiProtFlags) == 0)
|
{
|
ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN;
|
}
|
|
if ((uiProtFlags & MMU_PROTFLAGS_INVALID) == 0)
|
{
|
ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_VALID_EN;
|
}
|
|
if (MMU_PROTFLAGS_DEVICE(PMMETA_PROTECT) & uiProtFlags)
|
{
|
ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN;
|
}
|
|
return ui64MMUFlags;
|
}
|
|
|
/*************************************************************************/ /*!
|
@Function RGXGetPageSizeConfig
|
@Description Set up configuration for variable sized data pages.
|
RGXPutPageSizeConfigCB has to be called to ensure correct
|
refcounting.
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize,
|
const MMU_PxE_CONFIG **ppsMMUPDEConfig,
|
const MMU_PxE_CONFIG **ppsMMUPTEConfig,
|
const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig,
|
IMG_HANDLE *phPriv)
|
{
|
MMU_PAGESIZECONFIG *psPageSizeConfig;
|
|
switch (uiLog2DataPageSize)
|
{
|
case RGX_HEAP_4KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig4KB;
|
break;
|
case RGX_HEAP_16KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig16KB;
|
break;
|
case RGX_HEAP_64KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig64KB;
|
break;
|
case RGX_HEAP_256KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig256KB;
|
break;
|
case RGX_HEAP_1MB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig1MB;
|
break;
|
case RGX_HEAP_2MB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig2MB;
|
break;
|
default:
|
PVR_DPF((PVR_DBG_ERROR,
|
"RGXGetPageSizeConfigCB: Invalid Data Page Size 1<<0x%x",
|
uiLog2DataPageSize));
|
return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
|
}
|
|
/* Refer caller's pointers to the data */
|
*ppsMMUPDEConfig = psPageSizeConfig->psPDEConfig;
|
*ppsMMUPTEConfig = psPageSizeConfig->psPTEConfig;
|
*ppsMMUDevVAddrConfig = psPageSizeConfig->psDevVAddrConfig;
|
|
#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT)
|
/* Increment ref-count - not that we're allocating anything here
|
(I'm using static structs), but one day we might, so we want
|
the Get/Put code to be balanced properly */
|
psPageSizeConfig->uiRefCount ++;
|
|
/* This is purely for debug statistics */
|
psPageSizeConfig->uiMaxRefCount = MAX(psPageSizeConfig->uiMaxRefCount,
|
psPageSizeConfig->uiRefCount);
|
#endif
|
|
*phPriv = (IMG_HANDLE)(uintptr_t)uiLog2DataPageSize;
|
PVR_ASSERT (uiLog2DataPageSize == (IMG_UINT32)(uintptr_t)*phPriv);
|
|
return PVRSRV_OK;
|
}
|
|
/*************************************************************************/ /*!
|
@Function RGXPutPageSizeConfig
|
@Description Tells this code that the mmu module is done with the
|
configurations set in RGXGetPageSizeConfig. This can
|
be a no-op.
|
Called after RGXGetPageSizeConfigCB.
|
@Return PVRSRV_ERROR
|
*/ /**************************************************************************/
|
static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv)
|
{
|
#if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT)
|
MMU_PAGESIZECONFIG *psPageSizeConfig;
|
IMG_UINT32 uiLog2DataPageSize;
|
|
uiLog2DataPageSize = (IMG_UINT32)(uintptr_t) hPriv;
|
|
switch (uiLog2DataPageSize)
|
{
|
case RGX_HEAP_4KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig4KB;
|
break;
|
case RGX_HEAP_16KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig16KB;
|
break;
|
case RGX_HEAP_64KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig64KB;
|
break;
|
case RGX_HEAP_256KB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig256KB;
|
break;
|
case RGX_HEAP_1MB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig1MB;
|
break;
|
case RGX_HEAP_2MB_PAGE_SHIFT:
|
psPageSizeConfig = &gsPageSizeConfig2MB;
|
break;
|
default:
|
PVR_DPF((PVR_DBG_ERROR,
|
"RGXPutPageSizeConfigCB: Invalid Data Page Size 1<<0x%x",
|
uiLog2DataPageSize));
|
return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
|
}
|
|
/* Ref-count here is not especially useful, but it's an extra
|
check that the API is being used correctly */
|
psPageSizeConfig->uiRefCount --;
|
#else
|
PVR_UNREFERENCED_PARAMETER(hPriv);
|
#endif
|
return PVRSRV_OK;
|
}
|
|
static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize)
|
{
|
PVR_UNREFERENCED_PARAMETER(ui32PDE);
|
PVR_UNREFERENCED_PARAMETER(pui32Log2PageSize);
|
PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device"));
|
return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
|
}
|
|
static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize)
|
{
|
switch (ui64PDE & (~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK))
|
{
|
case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB:
|
*pui32Log2PageSize = RGX_HEAP_4KB_PAGE_SHIFT;
|
break;
|
case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB:
|
*pui32Log2PageSize = RGX_HEAP_16KB_PAGE_SHIFT;
|
break;
|
case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB:
|
*pui32Log2PageSize = RGX_HEAP_64KB_PAGE_SHIFT;
|
break;
|
case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB:
|
*pui32Log2PageSize = RGX_HEAP_256KB_PAGE_SHIFT;
|
break;
|
case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB:
|
*pui32Log2PageSize = RGX_HEAP_1MB_PAGE_SHIFT;
|
break;
|
case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB:
|
*pui32Log2PageSize = RGX_HEAP_2MB_PAGE_SHIFT;
|
break;
|
default:
|
return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
|
}
|
return PVRSRV_OK;
|
}
|