/*
* Copyright ( c ) 2015 Google Inc . All rights reserved
*
* 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 .
*
* 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 .
* 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 <arch/mmu.h>
#include <assert.h>
#include <debug.h>
#include <err.h>
#include <inttypes.h>
#include <lib/sm.h>
#include <trace.h>
#define LOCAL_TRACE 0
/* 48-bit physical address 47:12 */
#define NS_PTE_PHYSADDR_MASK (0 xFFFFFFFFF000ULL)
#define NS_PTE_PHYSADDR(pte) ((pte) & (NS_PTE_PHYSADDR_MASK))
#define NS_PTE_ATTR(pte) ((pte) & ~(NS_PTE_PHYSADDR_MASK))
/* Access permissions AP[2:1]
* EL0 EL1
* 00 None RW
* 01 RW RW
* 10 None RO
* 11 RO RO
*/
#define NS_PTE_AP(pte) (((pte) >> 6 ) & 0 x3)
#define NS_PTE_AP_U_RW(pte) (NS_PTE_AP(pte) == 0 x1)
#define NS_PTE_AP_U(pte) (NS_PTE_AP(pte) & 0 x1)
#define NS_PTE_AP_RO(pte) (NS_PTE_AP(pte) & 0 x2)
/* Shareablility attrs */
#define NS_PTE_ATTR_SHAREABLE(pte) (((pte) >> 8 ) & 0 x3)
/* cache attrs encoded in the top bits 55:49 of the PTE*/
#define NS_PTE_ATTR_MAIR(pte) (((pte) >> 48 ) & 0 xFF)
/* Inner cache attrs MAIR_ATTR_N[3:0] */
#define NS_PTE_ATTR_INNER(pte) ((NS_PTE_ATTR_MAIR(pte)) & 0 xF)
/* Outer cache attrs MAIR_ATTR_N[7:4] */
#define NS_PTE_ATTR_OUTER(pte) (((NS_PTE_ATTR_MAIR(pte)) & 0 xF0) >> 4 )
/* Normal memory */
/* inner and outer write back read/write allocate */
#define NS_MAIR_NORMAL_CACHED_WB_RWA 0 xFF
/* inner and outer write back read/write allocate tagged */
#define NS_MAIR_NORMAL_CACHED_WB_RWA_TAGGED 0 xF0
/* inner and outer write through read allocate */
#define NS_MAIR_NORMAL_CACHED_WT_RA 0 xAA
/* inner and outer wriet back, read allocate */
#define NS_MAIR_NORMAL_CACHED_WB_RA 0 xEE
/* uncached */
#define NS_MAIR_NORMAL_UNCACHED 0 x44
/* Device memory */
/* nGnRnE (strongly ordered) */
#define NS_MAIR_DEVICE_STRONGLY_ORDERED 0 x00
/* nGnRE (device) */
#define NS_MAIR_DEVICE 0 x04
/* GRE */
#define NS_MAIR_DEVICE_GRE 0 x0C
/* sharaeble attributes */
#define NS_NON_SHAREABLE 0 x0
#define NS_OUTER_SHAREABLE 0 x2
#define NS_INNER_SHAREABLE 0 x3
#define NS_PTE_ATTR_DEFAULT_CACHED \
((uint64_t)NS_MAIR_NORMAL_CACHED_WB_RWA << 48 | NS_INNER_SHAREABLE << 8 )
/* helper function to decode ns memory attrubutes */
status_t sm_decode_ns_memory_attr(struct ns_page_info* pinf,
ns_addr_t* ppa,
uint* pmmu) {
uint mmu_flags = 0 ;
if (!pinf)
return ERR_INVALID_ARGS;
LTRACEF("raw=0x%" PRIx64 ": pa=0x%llx: mair=0x%x, sharable=0x%x\n" ,
pinf->attr, NS_PTE_PHYSADDR(pinf->attr),
(uint)NS_PTE_ATTR_MAIR(pinf->attr),
(uint)NS_PTE_ATTR_SHAREABLE(pinf->attr));
if (ppa)
*ppa = (ns_addr_t)NS_PTE_PHYSADDR(pinf->attr);
if (pmmu) {
uint64_t attr = NS_PTE_ATTR(pinf->attr);
if (attr == 0 ) {
if (sm_get_api_version() >= TRUSTY_API_VERSION_PHYS_MEM_OBJ) {
LTRACEF("Unsupported 0 memory attr\n" );
return ERR_NOT_SUPPORTED;
}
/*
* Some existing clients don ' t pass attibutes and assume cached
* write - able memory .
*/
attr = NS_PTE_ATTR_DEFAULT_CACHED;
}
/* match settings to mmu flags */
switch ((uint)NS_PTE_ATTR_MAIR(attr)) {
/*
* Normal tagged memory and normal untagged memory can be treated the
* same here , because we only ever map it as untagged in Trusty . This
* is enforced in vmm by only allowing pmm objecs to be tagged .
*/
case NS_MAIR_NORMAL_CACHED_WB_RWA:
case NS_MAIR_NORMAL_CACHED_WB_RWA_TAGGED:
mmu_flags |= ARCH_MMU_FLAG_CACHED;
break ;
case NS_MAIR_NORMAL_UNCACHED:
mmu_flags |= ARCH_MMU_FLAG_UNCACHED;
break ;
default :
LTRACEF("Unsupported memory attr 0x%x\n" ,
(uint)NS_PTE_ATTR_MAIR(attr));
return ERR_NOT_SUPPORTED;
}
#if WITH_SMP | WITH_SHAREABLE_CACHE
if (mmu_flags == ARCH_MMU_FLAG_CACHED) {
if (NS_PTE_ATTR_SHAREABLE(attr) != NS_INNER_SHAREABLE) {
LTRACEF("Unsupported sharable attr 0x%x\n" ,
(uint)NS_PTE_ATTR_SHAREABLE(attr));
return ERR_NOT_SUPPORTED;
}
}
#endif
if (NS_PTE_AP_U(attr))
mmu_flags |= ARCH_MMU_FLAG_PERM_USER;
if (NS_PTE_AP_RO(attr))
mmu_flags |= ARCH_MMU_FLAG_PERM_RO;
*pmmu = mmu_flags | ARCH_MMU_FLAG_NS | ARCH_MMU_FLAG_PERM_NO_EXECUTE;
}
return NO_ERROR;
}
Messung V0.5 in Prozent C=91 H=95 G=92
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-27)
¤
*© Formatika GbR, Deutschland