336 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only OR MIT */2/* Copyright (c) 2023 Imagination Technologies Ltd. */3 4#ifndef PVR_ROGUE_MIPS_H5#define PVR_ROGUE_MIPS_H6 7#include <linux/bits.h>8#include <linux/types.h>9 10/* Utility defines for memory management. */11#define ROGUE_MIPSFW_LOG2_PAGE_SIZE_4K (12)12#define ROGUE_MIPSFW_PAGE_SIZE_4K (0x1 << ROGUE_MIPSFW_LOG2_PAGE_SIZE_4K)13#define ROGUE_MIPSFW_PAGE_MASK_4K (ROGUE_MIPSFW_PAGE_SIZE_4K - 1)14#define ROGUE_MIPSFW_LOG2_PAGE_SIZE_64K (16)15#define ROGUE_MIPSFW_PAGE_SIZE_64K (0x1 << ROGUE_MIPSFW_LOG2_PAGE_SIZE_64K)16#define ROGUE_MIPSFW_PAGE_MASK_64K (ROGUE_MIPSFW_PAGE_SIZE_64K - 1)17#define ROGUE_MIPSFW_LOG2_PAGE_SIZE_256K (18)18#define ROGUE_MIPSFW_PAGE_SIZE_256K (0x1 << ROGUE_MIPSFW_LOG2_PAGE_SIZE_256K)19#define ROGUE_MIPSFW_PAGE_MASK_256K (ROGUE_MIPSFW_PAGE_SIZE_256K - 1)20#define ROGUE_MIPSFW_LOG2_PAGE_SIZE_1MB (20)21#define ROGUE_MIPSFW_PAGE_SIZE_1MB (0x1 << ROGUE_MIPSFW_LOG2_PAGE_SIZE_1MB)22#define ROGUE_MIPSFW_PAGE_MASK_1MB (ROGUE_MIPSFW_PAGE_SIZE_1MB - 1)23#define ROGUE_MIPSFW_LOG2_PAGE_SIZE_4MB (22)24#define ROGUE_MIPSFW_PAGE_SIZE_4MB (0x1 << ROGUE_MIPSFW_LOG2_PAGE_SIZE_4MB)25#define ROGUE_MIPSFW_PAGE_MASK_4MB (ROGUE_MIPSFW_PAGE_SIZE_4MB - 1)26#define ROGUE_MIPSFW_LOG2_PTE_ENTRY_SIZE (2)27/* log2 page table sizes dependent on FW heap size and page size (for each OS). */28#define ROGUE_MIPSFW_LOG2_PAGETABLE_SIZE_4K(pvr_dev) ((pvr_dev)->fw_dev.fw_heap_info.log2_size - \29 ROGUE_MIPSFW_LOG2_PAGE_SIZE_4K + \30 ROGUE_MIPSFW_LOG2_PTE_ENTRY_SIZE)31#define ROGUE_MIPSFW_LOG2_PAGETABLE_SIZE_64K(pvr_dev) ((pvr_dev)->fw_dev.fw_heap_info.log2_size - \32 ROGUE_MIPSFW_LOG2_PAGE_SIZE_64K + \33 ROGUE_MIPSFW_LOG2_PTE_ENTRY_SIZE)34/* Maximum number of page table pages (both Host and MIPS pages). */35#define ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES (4)36/* Total number of TLB entries. */37#define ROGUE_MIPSFW_NUMBER_OF_TLB_ENTRIES (16)38/* "Uncached" caching policy. */39#define ROGUE_MIPSFW_UNCACHED_CACHE_POLICY (2)40/* "Write-back write-allocate" caching policy. */41#define ROGUE_MIPSFW_WRITEBACK_CACHE_POLICY (3)42/* "Write-through no write-allocate" caching policy. */43#define ROGUE_MIPSFW_WRITETHROUGH_CACHE_POLICY (1)44/* Cached policy used by MIPS in case of physical bus on 32 bit. */45#define ROGUE_MIPSFW_CACHED_POLICY (ROGUE_MIPSFW_WRITEBACK_CACHE_POLICY)46/* Cached policy used by MIPS in case of physical bus on more than 32 bit. */47#define ROGUE_MIPSFW_CACHED_POLICY_ABOVE_32BIT (ROGUE_MIPSFW_WRITETHROUGH_CACHE_POLICY)48/* Total number of Remap entries. */49#define ROGUE_MIPSFW_NUMBER_OF_REMAP_ENTRIES (2 * ROGUE_MIPSFW_NUMBER_OF_TLB_ENTRIES)50 51/* MIPS EntryLo/PTE format. */52 53#define ROGUE_MIPSFW_ENTRYLO_READ_INHIBIT_SHIFT (31U)54#define ROGUE_MIPSFW_ENTRYLO_READ_INHIBIT_CLRMSK (0X7FFFFFFF)55#define ROGUE_MIPSFW_ENTRYLO_READ_INHIBIT_EN (0X80000000)56 57#define ROGUE_MIPSFW_ENTRYLO_EXEC_INHIBIT_SHIFT (30U)58#define ROGUE_MIPSFW_ENTRYLO_EXEC_INHIBIT_CLRMSK (0XBFFFFFFF)59#define ROGUE_MIPSFW_ENTRYLO_EXEC_INHIBIT_EN (0X40000000)60 61/* Page Frame Number */62#define ROGUE_MIPSFW_ENTRYLO_PFN_SHIFT (6)63#define ROGUE_MIPSFW_ENTRYLO_PFN_ALIGNSHIFT (12)64/* Mask used for the MIPS Page Table in case of physical bus on 32 bit. */65#define ROGUE_MIPSFW_ENTRYLO_PFN_MASK (0x03FFFFC0)66#define ROGUE_MIPSFW_ENTRYLO_PFN_SIZE (20)67/* Mask used for the MIPS Page Table in case of physical bus on more than 32 bit. */68#define ROGUE_MIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT (0x3FFFFFC0)69#define ROGUE_MIPSFW_ENTRYLO_PFN_SIZE_ABOVE_32BIT (24)70#define ROGUE_MIPSFW_ADDR_TO_ENTRYLO_PFN_RSHIFT (ROGUE_MIPSFW_ENTRYLO_PFN_ALIGNSHIFT - \71 ROGUE_MIPSFW_ENTRYLO_PFN_SHIFT)72 73#define ROGUE_MIPSFW_ENTRYLO_CACHE_POLICY_SHIFT (3U)74#define ROGUE_MIPSFW_ENTRYLO_CACHE_POLICY_CLRMSK (0XFFFFFFC7)75 76#define ROGUE_MIPSFW_ENTRYLO_DIRTY_SHIFT (2U)77#define ROGUE_MIPSFW_ENTRYLO_DIRTY_CLRMSK (0XFFFFFFFB)78#define ROGUE_MIPSFW_ENTRYLO_DIRTY_EN (0X00000004)79 80#define ROGUE_MIPSFW_ENTRYLO_VALID_SHIFT (1U)81#define ROGUE_MIPSFW_ENTRYLO_VALID_CLRMSK (0XFFFFFFFD)82#define ROGUE_MIPSFW_ENTRYLO_VALID_EN (0X00000002)83 84#define ROGUE_MIPSFW_ENTRYLO_GLOBAL_SHIFT (0U)85#define ROGUE_MIPSFW_ENTRYLO_GLOBAL_CLRMSK (0XFFFFFFFE)86#define ROGUE_MIPSFW_ENTRYLO_GLOBAL_EN (0X00000001)87 88#define ROGUE_MIPSFW_ENTRYLO_DVG (ROGUE_MIPSFW_ENTRYLO_DIRTY_EN | \89 ROGUE_MIPSFW_ENTRYLO_VALID_EN | \90 ROGUE_MIPSFW_ENTRYLO_GLOBAL_EN)91#define ROGUE_MIPSFW_ENTRYLO_UNCACHED (ROGUE_MIPSFW_UNCACHED_CACHE_POLICY << \92 ROGUE_MIPSFW_ENTRYLO_CACHE_POLICY_SHIFT)93#define ROGUE_MIPSFW_ENTRYLO_DVG_UNCACHED (ROGUE_MIPSFW_ENTRYLO_DVG | \94 ROGUE_MIPSFW_ENTRYLO_UNCACHED)95 96/* Remap Range Config Addr Out. */97/* These defines refer to the upper half of the Remap Range Config register. */98#define ROGUE_MIPSFW_REMAP_RANGE_ADDR_OUT_MASK (0x0FFFFFF0)99#define ROGUE_MIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT (4) /* wrt upper half of the register. */100#define ROGUE_MIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT (12)101#define ROGUE_MIPSFW_ADDR_TO_RR_ADDR_OUT_RSHIFT (ROGUE_MIPSFW_REMAP_RANGE_ADDR_OUT_ALIGNSHIFT - \102 ROGUE_MIPSFW_REMAP_RANGE_ADDR_OUT_SHIFT)103 104/*105 * Pages to trampoline problematic physical addresses:106 * - ROGUE_MIPSFW_BOOT_REMAP_PHYS_ADDR_IN : 0x1FC0_0000107 * - ROGUE_MIPSFW_DATA_REMAP_PHYS_ADDR_IN : 0x1FC0_1000108 * - ROGUE_MIPSFW_CODE_REMAP_PHYS_ADDR_IN : 0x1FC0_2000109 * - (benign trampoline) : 0x1FC0_3000110 * that would otherwise be erroneously remapped by the MIPS wrapper.111 * (see "Firmware virtual layout and remap configuration" section below)112 */113 114#define ROGUE_MIPSFW_TRAMPOLINE_LOG2_NUMPAGES (2)115#define ROGUE_MIPSFW_TRAMPOLINE_NUMPAGES BIT(ROGUE_MIPSFW_TRAMPOLINE_LOG2_NUMPAGES)116#define ROGUE_MIPSFW_TRAMPOLINE_SIZE (ROGUE_MIPSFW_TRAMPOLINE_NUMPAGES << \117 ROGUE_MIPSFW_LOG2_PAGE_SIZE_4K)118#define ROGUE_MIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE (ROGUE_MIPSFW_TRAMPOLINE_LOG2_NUMPAGES + \119 ROGUE_MIPSFW_LOG2_PAGE_SIZE_4K)120 121#define ROGUE_MIPSFW_TRAMPOLINE_TARGET_PHYS_ADDR (ROGUE_MIPSFW_BOOT_REMAP_PHYS_ADDR_IN)122#define ROGUE_MIPSFW_TRAMPOLINE_OFFSET(a) ((a) - ROGUE_MIPSFW_BOOT_REMAP_PHYS_ADDR_IN)123 124#define ROGUE_MIPSFW_SENSITIVE_ADDR(a) (ROGUE_MIPSFW_BOOT_REMAP_PHYS_ADDR_IN == \125 (~((1 << ROGUE_MIPSFW_TRAMPOLINE_LOG2_SEGMENT_SIZE) - 1) \126 & (a)))127 128/* Firmware virtual layout and remap configuration. */129/*130 * For each remap region we define:131 * - the virtual base used by the Firmware to access code/data through that region132 * - the microAptivAP physical address correspondent to the virtual base address,133 * used as input address and remapped to the actual physical address134 * - log2 of size of the region remapped by the MIPS wrapper, i.e. number of bits from135 * the bottom of the base input address that survive onto the output address136 * (this defines both the alignment and the maximum size of the remapped region)137 * - one or more code/data segments within the remapped region.138 */139 140/* Boot remap setup. */141#define ROGUE_MIPSFW_BOOT_REMAP_VIRTUAL_BASE (0xBFC00000)142#define ROGUE_MIPSFW_BOOT_REMAP_PHYS_ADDR_IN (0x1FC00000)143#define ROGUE_MIPSFW_BOOT_REMAP_LOG2_SEGMENT_SIZE (12)144#define ROGUE_MIPSFW_BOOT_NMI_CODE_VIRTUAL_BASE (ROGUE_MIPSFW_BOOT_REMAP_VIRTUAL_BASE)145 146/* Data remap setup. */147#define ROGUE_MIPSFW_DATA_REMAP_VIRTUAL_BASE (0xBFC01000)148#define ROGUE_MIPSFW_DATA_CACHED_REMAP_VIRTUAL_BASE (0x9FC01000)149#define ROGUE_MIPSFW_DATA_REMAP_PHYS_ADDR_IN (0x1FC01000)150#define ROGUE_MIPSFW_DATA_REMAP_LOG2_SEGMENT_SIZE (12)151#define ROGUE_MIPSFW_BOOT_NMI_DATA_VIRTUAL_BASE (ROGUE_MIPSFW_DATA_REMAP_VIRTUAL_BASE)152 153/* Code remap setup. */154#define ROGUE_MIPSFW_CODE_REMAP_VIRTUAL_BASE (0x9FC02000)155#define ROGUE_MIPSFW_CODE_REMAP_PHYS_ADDR_IN (0x1FC02000)156#define ROGUE_MIPSFW_CODE_REMAP_LOG2_SEGMENT_SIZE (12)157#define ROGUE_MIPSFW_EXCEPTIONS_VIRTUAL_BASE (ROGUE_MIPSFW_CODE_REMAP_VIRTUAL_BASE)158 159/* Permanent mappings setup. */160#define ROGUE_MIPSFW_PT_VIRTUAL_BASE (0xCF000000)161#define ROGUE_MIPSFW_REGISTERS_VIRTUAL_BASE (0xCF800000)162#define ROGUE_MIPSFW_STACK_VIRTUAL_BASE (0xCF600000)163 164/* Bootloader configuration data. */165/*166 * Bootloader configuration offset (where ROGUE_MIPSFW_BOOT_DATA lives)167 * within the bootloader/NMI data page.168 */169#define ROGUE_MIPSFW_BOOTLDR_CONF_OFFSET (0x0)170 171/* NMI shared data. */172/* Base address of the shared data within the bootloader/NMI data page. */173#define ROGUE_MIPSFW_NMI_SHARED_DATA_BASE (0x100)174/* Size used by Debug dump data. */175#define ROGUE_MIPSFW_NMI_SHARED_SIZE (0x2B0)176/* Offsets in the NMI shared area in 32-bit words. */177#define ROGUE_MIPSFW_NMI_SYNC_FLAG_OFFSET (0x0)178#define ROGUE_MIPSFW_NMI_STATE_OFFSET (0x1)179#define ROGUE_MIPSFW_NMI_ERROR_STATE_SET (0x1)180 181/* MIPS boot stage. */182#define ROGUE_MIPSFW_BOOT_STAGE_OFFSET (0x400)183 184/*185 * MIPS private data in the bootloader data page.186 * Memory below this offset is used by the FW only, no interface data allowed.187 */188#define ROGUE_MIPSFW_PRIVATE_DATA_OFFSET (0x800)189 190struct rogue_mipsfw_boot_data {191 u64 stack_phys_addr;192 u64 reg_base;193 u64 pt_phys_addr[ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES];194 u32 pt_log2_page_size;195 u32 pt_num_pages;196 u32 reserved1;197 u32 reserved2;198};199 200#define ROGUE_MIPSFW_GET_OFFSET_IN_DWORDS(offset) ((offset) / sizeof(u32))201#define ROGUE_MIPSFW_GET_OFFSET_IN_QWORDS(offset) ((offset) / sizeof(u64))202 203/* Used for compatibility checks. */204#define ROGUE_MIPSFW_ARCHTYPE_VER_CLRMSK (0xFFFFE3FFU)205#define ROGUE_MIPSFW_ARCHTYPE_VER_SHIFT (10U)206#define ROGUE_MIPSFW_CORE_ID_VALUE (0x001U)207#define ROGUE_FW_PROCESSOR_MIPS "MIPS"208 209/* microAptivAP cache line size. */210#define ROGUE_MIPSFW_MICROAPTIVEAP_CACHELINE_SIZE (16U)211 212/*213 * The SOCIF transactions are identified with the top 16 bits of the physical address emitted by214 * the MIPS.215 */216#define ROGUE_MIPSFW_WRAPPER_CONFIG_REGBANK_ADDR_ALIGN (16U)217 218/* Values to put in the MIPS selectors for performance counters. */219/* Icache accesses in COUNTER0. */220#define ROGUE_MIPSFW_PERF_COUNT_CTRL_ICACHE_ACCESSES_C0 (9U)221/* Icache misses in COUNTER1. */222#define ROGUE_MIPSFW_PERF_COUNT_CTRL_ICACHE_MISSES_C1 (9U)223 224/* Dcache accesses in COUNTER0. */225#define ROGUE_MIPSFW_PERF_COUNT_CTRL_DCACHE_ACCESSES_C0 (10U)226/* Dcache misses in COUNTER1. */227#define ROGUE_MIPSFW_PERF_COUNT_CTRL_DCACHE_MISSES_C1 (11U)228 229/* ITLB instruction accesses in COUNTER0. */230#define ROGUE_MIPSFW_PERF_COUNT_CTRL_ITLB_INSTR_ACCESSES_C0 (5U)231/* JTLB instruction accesses misses in COUNTER1. */232#define ROGUE_MIPSFW_PERF_COUNT_CTRL_JTLB_INSTR_MISSES_C1 (7U)233 234 /* Instructions completed in COUNTER0. */235#define ROGUE_MIPSFW_PERF_COUNT_CTRL_INSTR_COMPLETED_C0 (1U)236/* JTLB data misses in COUNTER1. */237#define ROGUE_MIPSFW_PERF_COUNT_CTRL_JTLB_DATA_MISSES_C1 (8U)238 239/* Shift for the Event field in the MIPS perf ctrl registers. */240#define ROGUE_MIPSFW_PERF_COUNT_CTRL_EVENT_SHIFT (5U)241 242/* Additional flags for performance counters. See MIPS manual for further reference. */243#define ROGUE_MIPSFW_PERF_COUNT_CTRL_COUNT_USER_MODE (8U)244#define ROGUE_MIPSFW_PERF_COUNT_CTRL_COUNT_KERNEL_MODE (2U)245#define ROGUE_MIPSFW_PERF_COUNT_CTRL_COUNT_EXL (1U)246 247#define ROGUE_MIPSFW_C0_NBHWIRQ 8248 249/* Macros to decode C0_Cause register. */250#define ROGUE_MIPSFW_C0_CAUSE_EXCCODE(cause) (((cause) & 0x7c) >> 2)251#define ROGUE_MIPSFW_C0_CAUSE_EXCCODE_FWERROR 9252/* Use only when Coprocessor Unusable exception. */253#define ROGUE_MIPSFW_C0_CAUSE_UNUSABLE_UNIT(cause) (((cause) >> 28) & 0x3)254#define ROGUE_MIPSFW_C0_CAUSE_PENDING_HWIRQ(cause) (((cause) & 0x3fc00) >> 10)255#define ROGUE_MIPSFW_C0_CAUSE_FDCIPENDING BIT(21)256#define ROGUE_MIPSFW_C0_CAUSE_IV BIT(23)257#define ROGUE_MIPSFW_C0_CAUSE_IC BIT(25)258#define ROGUE_MIPSFW_C0_CAUSE_PCIPENDING BIT(26)259#define ROGUE_MIPSFW_C0_CAUSE_TIPENDING BIT(30)260#define ROGUE_MIPSFW_C0_CAUSE_BRANCH_DELAY BIT(31)261 262/* Macros to decode C0_Debug register. */263#define ROGUE_MIPSFW_C0_DEBUG_EXCCODE(debug) (((debug) >> 10) & 0x1f)264#define ROGUE_MIPSFW_C0_DEBUG_DSS BIT(0)265#define ROGUE_MIPSFW_C0_DEBUG_DBP BIT(1)266#define ROGUE_MIPSFW_C0_DEBUG_DDBL BIT(2)267#define ROGUE_MIPSFW_C0_DEBUG_DDBS BIT(3)268#define ROGUE_MIPSFW_C0_DEBUG_DIB BIT(4)269#define ROGUE_MIPSFW_C0_DEBUG_DINT BIT(5)270#define ROGUE_MIPSFW_C0_DEBUG_DIBIMPR BIT(6)271#define ROGUE_MIPSFW_C0_DEBUG_DDBLIMPR BIT(18)272#define ROGUE_MIPSFW_C0_DEBUG_DDBSIMPR BIT(19)273#define ROGUE_MIPSFW_C0_DEBUG_IEXI BIT(20)274#define ROGUE_MIPSFW_C0_DEBUG_DBUSEP BIT(21)275#define ROGUE_MIPSFW_C0_DEBUG_CACHEEP BIT(22)276#define ROGUE_MIPSFW_C0_DEBUG_MCHECKP BIT(23)277#define ROGUE_MIPSFW_C0_DEBUG_IBUSEP BIT(24)278#define ROGUE_MIPSFW_C0_DEBUG_DM BIT(30)279#define ROGUE_MIPSFW_C0_DEBUG_DBD BIT(31)280 281/* Macros to decode TLB entries. */282#define ROGUE_MIPSFW_TLB_GET_MASK(page_mask) (((page_mask) >> 13) & 0XFFFFU)283/* Page size in KB. */284#define ROGUE_MIPSFW_TLB_GET_PAGE_SIZE(page_mask) ((((page_mask) | 0x1FFF) + 1) >> 11)285/* Page size in KB. */286#define ROGUE_MIPSFW_TLB_GET_PAGE_MASK(page_size) ((((page_size) << 11) - 1) & ~0x7FF)287#define ROGUE_MIPSFW_TLB_GET_VPN2(entry_hi) ((entry_hi) >> 13)288#define ROGUE_MIPSFW_TLB_GET_COHERENCY(entry_lo) (((entry_lo) >> 3) & 0x7U)289#define ROGUE_MIPSFW_TLB_GET_PFN(entry_lo) (((entry_lo) >> 6) & 0XFFFFFU)290/* GET_PA uses a non-standard PFN mask for 36 bit addresses. */291#define ROGUE_MIPSFW_TLB_GET_PA(entry_lo) (((u64)(entry_lo) & \292 ROGUE_MIPSFW_ENTRYLO_PFN_MASK_ABOVE_32BIT) << 6)293#define ROGUE_MIPSFW_TLB_GET_INHIBIT(entry_lo) (((entry_lo) >> 30) & 0x3U)294#define ROGUE_MIPSFW_TLB_GET_DGV(entry_lo) ((entry_lo) & 0x7U)295#define ROGUE_MIPSFW_TLB_GLOBAL BIT(0)296#define ROGUE_MIPSFW_TLB_VALID BIT(1)297#define ROGUE_MIPSFW_TLB_DIRTY BIT(2)298#define ROGUE_MIPSFW_TLB_XI BIT(30)299#define ROGUE_MIPSFW_TLB_RI BIT(31)300 301#define ROGUE_MIPSFW_REMAP_GET_REGION_SIZE(region_size_encoding) (1 << (((region_size_encoding) \302 + 1) << 1))303 304struct rogue_mips_tlb_entry {305 u32 tlb_page_mask;306 u32 tlb_hi;307 u32 tlb_lo0;308 u32 tlb_lo1;309};310 311struct rogue_mips_remap_entry {312 u32 remap_addr_in; /* Always 4k aligned. */313 u32 remap_addr_out; /* Always 4k aligned. */314 u32 remap_region_size;315};316 317struct rogue_mips_state {318 u32 error_state; /* This must come first in the structure. */319 u32 error_epc;320 u32 status_register;321 u32 cause_register;322 u32 bad_register;323 u32 epc;324 u32 sp;325 u32 debug;326 u32 depc;327 u32 bad_instr;328 u32 unmapped_address;329 struct rogue_mips_tlb_entry tlb[ROGUE_MIPSFW_NUMBER_OF_TLB_ENTRIES];330 struct rogue_mips_remap_entry remap[ROGUE_MIPSFW_NUMBER_OF_REMAP_ENTRIES];331};332 333#include "pvr_rogue_mips_check.h"334 335#endif /* PVR_ROGUE_MIPS_H */336