/*************************************************************************/ /*! @File rgx_mips.h @Title @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved @Platform RGX @Description RGX MIPS definitions, kernel/user space @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. */ /**************************************************************************/ #if !defined(RGX_MIPS_H) #define RGX_MIPS_H /* * Utility defines for memory management */ #define RGXMIPSFW_LOG2_PAGE_SIZE_4K (12) #define RGXMIPSFW_PAGE_SIZE_4K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_4K) #define RGXMIPSFW_PAGE_MASK_4K (RGXMIPSFW_PAGE_SIZE_4K - 1) #define RGXMIPSFW_LOG2_PAGE_SIZE_64K (16) #define RGXMIPSFW_PAGE_SIZE_64K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_64K) #define RGXMIPSFW_PAGE_MASK_64K (RGXMIPSFW_PAGE_SIZE_64K - 1) #define RGXMIPSFW_LOG2_PAGE_SIZE_256K (18) #define RGXMIPSFW_PAGE_SIZE_256K (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_256K) #define RGXMIPSFW_PAGE_MASK_256K (RGXMIPSFW_PAGE_SIZE_256K - 1) #define RGXMIPSFW_LOG2_PAGE_SIZE_1MB (20) #define RGXMIPSFW_PAGE_SIZE_1MB (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_1MB) #define RGXMIPSFW_PAGE_MASK_1MB (RGXMIPSFW_PAGE_SIZE_1MB - 1) #define RGXMIPSFW_LOG2_PAGE_SIZE_4MB (22) #define RGXMIPSFW_PAGE_SIZE_4MB (0x1 << RGXMIPSFW_LOG2_PAGE_SIZE_4MB) #define RGXMIPSFW_PAGE_MASK_4MB (RGXMIPSFW_PAGE_SIZE_4MB - 1) #define RGXMIPSFW_LOG2_PTE_ENTRY_SIZE (2) /* log2 page table sizes dependent on FW heap size and page size (for each OS) */ #define RGXMIPSFW_LOG2_PAGETABLE_SIZE_4K (RGX_FIRMWARE_HEAP_SHIFT - RGXMIPSFW_LOG2_PAGE_SIZE_4K + RGXMIPSFW_LOG2_PTE_ENTRY_SIZE) #define RGXMIPSFW_LOG2_PAGETABLE_SIZE_64K (RGX_FIRMWARE_HEAP_SHIFT - RGXMIPSFW_LOG2_PAGE_SIZE_64K + RGXMIPSFW_LOG2_PTE_ENTRY_SIZE) /* Maximum log2 page table size (across OSes) */ #define RGXMIPSFW_MAX_LOG2_PAGETABLE_SIZE (18) /* 256KB page table */ /* Maximum number of page table pages (both Host and MIPS pages) */ #define RGXMIPSFW_MAX_NUM_PAGETABLE_PAGES (4) /* Total number of TLB entries */ #define RGXMIPSFW_NUMBER_OF_TLB_ENTRIES (16) /* "Uncached" caching policy */ #define RGXMIPSFW_UNCACHED_CACHE_POLICY (0X00000002) /* "Write-back write-allocate" caching policy */ #define RGXMIPSFW_WRITEBACK_CACHE_POLICY (0X00000003) /* "Write-through no write-allocate" caching policy */ #define RGXMIPSFW_WRITETHROUGH_CACHE_POLICY (0X00000001) /* Cached policy used by MIPS in case of physical bus on 32 bit */ #define RGXMIPSFW_CACHED_POLICY (RGXMIPSFW_WRITEBACK_CACHE_POLICY) /* Cached policy used by MIPS in case of physical bus on more than 32 bit */ #define RGXMIPSFW_CACHED_POLICY_ABOVE_32BIT (RGXMIPSFW_WRITETHROUGH_CACHE_POLICY) /* Total number of Remap entries */ #define RGXMIPSFW_NUMBER_OF_REMAP_ENTRIES (2 * RGXMIPSFW_NUMBER_OF_TLB_ENTRIES) /* * MIPS EntryLo/PTE format */ #define RGXMIPSFW_ENTRYLO_READ_INHIBIT_SHIFT (31U) #define RGXMIPSFW_ENTRYLO_READ_INHIBIT_CLRMSK (0X7FFFFFFF) #define RGXMIPSFW_ENTRYLO_READ_INHIBIT_EN (0X80000000) #define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_SHIFT (30U) #define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_CLRMSK (0XBFFFFFFF) #define RGXMIPSFW_ENTRYLO_EXEC_INHIBIT_EN (0X40000000) /* Page Frame Number */ #define RGXMIPSFW_ENTRYLO_PFN_SHIFT (6) #define RGXMIPSFW_ENTRYLO_PFN_ALIGNSHIFT (12) /* Mask used for the MIPS Page Table in case of physical bus on 32 bit */ #define RGXMIPSFW_ENTRYLO_PFN_MASK (0x03FFFFC0) #define RGXMIPSFW_ENTRYLO_PFN_SIZE (20) /* Mask used for the MIPS Page Table in case of physical bus on more than 32 bit */ #define RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT (0x3FFFFFC0) #define RGXMIPSFW_ENTRYLO_PFN_SIZE_ABOVE_32BIT (24) #define RGXMIPSFW_ADDR_TO_ENTRYLO_PFN_RSHIFT (RGXMIPSFW_ENTRYLO_PFN_ALIGNSHIFT - \ RGXMIPSFW_ENTRYLO_PFN_SHIFT) #define RGXMIPSFW_ENTRYLO_CACHE_POLICY_SHIFT (3U) #define RGXMIPSFW_ENTRYLO_CACHE_POLICY_CLRMSK (0XFFFFFFC7) #define RGXMIPSFW_ENTRYLO_DIRTY_SHIFT (2U) #define RGXMIPSFW_ENTRYLO_DIRTY_CLRMSK (0XFFFFFFFB) #define RGXMIPSFW_ENTRYLO_DIRTY_EN (0X00000004) #define RGXMIPSFW_ENTRYLO_VALID_SHIFT (1U) #define RGXMIPSFW_ENTRYLO_VALID_CLRMSK (0XFFFFFFFD) #define RGXMIPSFW_ENTRYLO_VALID_EN (0X00000002) #define RGXMIPSFW_ENTRYLO_GLOBAL_SHIFT (0U) #define RGXMIPSFW_ENTRYLO_GLOBAL_CLRMSK (0XFFFFFFFE) #define RGXMIPSFW_ENTRYLO_GLOBAL_EN (0X00000001) #define RGXMIPSFW_ENTRYLO_DVG (RGXMIPSFW_ENTRYLO_DIRTY_EN | \ RGXMIPSFW_ENTRYLO_VALID_EN | \ RGXMIPSFW_ENTRYLO_GLOBAL_EN) #define RGXMIPSFW_ENTRYLO_UNCACHED (RGXMIPSFW_UNCACHED_CACHE_POLICY << \ RGXMIPSFW_ENTRYLO_CACHE_POLICY_SHIFT) #define RGXMIPSFW_ENTRYLO_DVG_UNCACHED (RGXMIPSFW_ENTRYLO_DVG | RGXMIPSFW_ENTRYLO_UNCACHED) /* Remap Range Config Addr Out */ /* These defines refer to the upper half of the Remap Range Config register */ #define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_MASK (0x0FFFFFF0) #define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT (4) /* wrt upper half of the register */ #define RGXMIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT (12) #define RGXMIPSFW_ADDR_TO_RR_ADDR_OUT_RSHIFT (RGXMIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT - \ RGXMIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT) #if defined(SECURE_FW_CODE_OSID) && (SECURE_FW_CODE_OSID + 1 > 2) #define MIPS_FW_CODE_OSID (SECURE_FW_CODE_OSID) #elif defined(SECURE_FW_CODE_OSID) #define MIPS_FW_CODE_OSID (1U) #endif /* * Pages to trampoline problematic physical addresses: * - RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN : 0x1FC0_0000 * - RGXMIPSFW_DATA_REMAP_PHYS_ADDR_IN : 0x1FC0_1000 * - RGXMIPSFW_CODE_REMAP_PHYS_ADDR_IN : 0x1FC0_2000 * - (benign trampoline) : 0x1FC0_3000 * that would otherwise be erroneously remapped by the MIPS wrapper * (see "Firmware virtual layout and remap configuration" section below) */ #define RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES (2) #define RGXMIPSFW_TRAMPOLINE_NUMPAGES (1 << RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES) #define RGXMIPSFW_TRAMPOLINE_SIZE (RGXMIPSFW_TRAMPOLINE_NUMPAGES << RGXMIPSFW_LOG2_PAGE_SIZE_4K) #define RGXMIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE (RGXMIPSFW_TRAMPOLINE_LOG2_NUMPAGES + RGXMIPSFW_LOG2_PAGE_SIZE_4K) #define RGXMIPSFW_TRAMPOLINE_TARGET_PHYS_ADDR (RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN) #define RGXMIPSFW_TRAMPOLINE_OFFSET(a) (a - RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN) #define RGXMIPSFW_SENSITIVE_ADDR(a) (RGXMIPSFW_BOOT_REMAP_PHYS_ADDR_IN == (~((1<> 2) #define RGXMIPSFW_C0_CAUSE_EXCCODE_FWERROR 9 /* Use only when Coprocessor Unusable exception */ #define RGXMIPSFW_C0_CAUSE_UNUSABLE_UNIT(CAUSE) (((CAUSE) >> 28) & 0x3) #define RGXMIPSFW_C0_CAUSE_PENDING_HWIRQ(CAUSE) (((CAUSE) & 0x3fc00) >> 10) #define RGXMIPSFW_C0_CAUSE_FDCIPENDING (1 << 21) #define RGXMIPSFW_C0_CAUSE_IV (1 << 23) #define RGXMIPSFW_C0_CAUSE_IC (1 << 25) #define RGXMIPSFW_C0_CAUSE_PCIPENDING (1 << 26) #define RGXMIPSFW_C0_CAUSE_TIPENDING (1 << 30) #define RGXMIPSFW_C0_CAUSE_BRANCH_DELAY (1 << 31) /* Macros to decode C0_Debug register */ #define RGXMIPSFW_C0_DEBUG_EXCCODE(DEBUG) (((DEBUG) >> 10) & 0x1f) #define RGXMIPSFW_C0_DEBUG_DSS (1 << 0) #define RGXMIPSFW_C0_DEBUG_DBP (1 << 1) #define RGXMIPSFW_C0_DEBUG_DDBL (1 << 2) #define RGXMIPSFW_C0_DEBUG_DDBS (1 << 3) #define RGXMIPSFW_C0_DEBUG_DIB (1 << 4) #define RGXMIPSFW_C0_DEBUG_DINT (1 << 5) #define RGXMIPSFW_C0_DEBUG_DIBIMPR (1 << 6) #define RGXMIPSFW_C0_DEBUG_DDBLIMPR (1 << 18) #define RGXMIPSFW_C0_DEBUG_DDBSIMPR (1 << 19) #define RGXMIPSFW_C0_DEBUG_IEXI (1 << 20) #define RGXMIPSFW_C0_DEBUG_DBUSEP (1 << 21) #define RGXMIPSFW_C0_DEBUG_CACHEEP (1 << 22) #define RGXMIPSFW_C0_DEBUG_MCHECKP (1 << 23) #define RGXMIPSFW_C0_DEBUG_IBUSEP (1 << 24) #define RGXMIPSFW_C0_DEBUG_DM (1 << 30) #define RGXMIPSFW_C0_DEBUG_DBD (1 << 31) /* Macros to decode TLB entries */ #define RGXMIPSFW_TLB_GET_MASK(PAGE_MASK) (((PAGE_MASK) >> 13) & 0XFFFFU) #define RGXMIPSFW_TLB_GET_PAGE_SIZE(PAGE_MASK) ((((PAGE_MASK) | 0x1FFF) + 1) >> 11) /* page size in KB */ #define RGXMIPSFW_TLB_GET_PAGE_MASK(PAGE_SIZE) ((((PAGE_SIZE) << 11) - 1) & ~0x7FF) /* page size in KB */ #define RGXMIPSFW_TLB_GET_VPN2(ENTRY_HI) ((ENTRY_HI) >> 13) #define RGXMIPSFW_TLB_GET_COHERENCY(ENTRY_LO) (((ENTRY_LO) >> 3) & 0x7U) #define RGXMIPSFW_TLB_GET_PFN(ENTRY_LO) (((ENTRY_LO) >> 6) & 0XFFFFFU) /* GET_PA uses a non-standard PFN mask for 36 bit addresses */ #define RGXMIPSFW_TLB_GET_PA(ENTRY_LO) (((IMG_UINT64)(ENTRY_LO) & RGXMIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT) << 6) #define RGXMIPSFW_TLB_GET_INHIBIT(ENTRY_LO) (((ENTRY_LO) >> 30) & 0x3U) #define RGXMIPSFW_TLB_GET_DGV(ENTRY_LO) ((ENTRY_LO) & 0x7U) #define RGXMIPSFW_TLB_GLOBAL (1U) #define RGXMIPSFW_TLB_VALID (1U << 1) #define RGXMIPSFW_TLB_DIRTY (1U << 2) #define RGXMIPSFW_TLB_XI (1U << 30) #define RGXMIPSFW_TLB_RI (1U << 31) #define RGXMIPSFW_REMAP_GET_REGION_SIZE(REGION_SIZE_ENCODING) (1 << ((REGION_SIZE_ENCODING + 1) << 1)) typedef struct { IMG_UINT32 ui32TLBPageMask; IMG_UINT32 ui32TLBHi; IMG_UINT32 ui32TLBLo0; IMG_UINT32 ui32TLBLo1; } RGX_MIPS_TLB_ENTRY; typedef struct { IMG_UINT32 ui32RemapAddrIn; /* always 4k aligned */ IMG_UINT32 ui32RemapAddrOut; /* always 4k aligned */ IMG_UINT32 ui32RemapRegionSize; } RGX_MIPS_REMAP_ENTRY; typedef struct { IMG_UINT32 ui32ErrorState; /* This must come first in the structure */ IMG_UINT32 ui32ErrorEPC; IMG_UINT32 ui32StatusRegister; IMG_UINT32 ui32CauseRegister; IMG_UINT32 ui32BadRegister; IMG_UINT32 ui32EPC; IMG_UINT32 ui32SP; IMG_UINT32 ui32Debug; IMG_UINT32 ui32DEPC; IMG_UINT32 ui32BadInstr; IMG_UINT32 ui32UnmappedAddress; RGX_MIPS_TLB_ENTRY asTLB[RGXMIPSFW_NUMBER_OF_TLB_ENTRIES]; RGX_MIPS_REMAP_ENTRY asRemap[RGXMIPSFW_NUMBER_OF_REMAP_ENTRIES]; } RGX_MIPS_STATE; #endif /* RGXMIPSFW_ASSEMBLY_CODE */ #endif /* RGX_MIPS_H */