1 /*
2 * Copyright (c) 2023, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     oca_rtlog_section_mgr.cpp
24 //! \brief    OCA rtlog section manager
25 //!
26 
27 #include "oca_rtlog_section_mgr.h"
28 #include "mos_utilities.h"
29 
30 #define ADDRESS_PAGE_ALIGNMENT_MASK 0xFFFFFFFFFFFFF000ULL
31 
32 OcaRtLogSectionMgr  OcaRtLogSectionMgr::s_rtLogSectionMgr[MOS_OCA_RTLOG_COMPONENT_MAX] = {};
33 uint8_t             OcaRtLogSectionMgr::s_localSysMem[MAX_OCA_RT_POOL_SIZE] = {};
34 
OcaRtLogSectionMgr()35 OcaRtLogSectionMgr::OcaRtLogSectionMgr()
36 {
37 }
38 
~OcaRtLogSectionMgr()39 OcaRtLogSectionMgr::~OcaRtLogSectionMgr()
40 {
41     m_LockedHeap    = nullptr;
42     m_HeapSize      = 0;
43     m_Offset        = 0;
44     m_HeapHandle    = -1;
45     m_IsInitialized = false;
46 }
47 
GetMemAddress()48 uint8_t *OcaRtLogSectionMgr::GetMemAddress()
49 {
50     static uint8_t *heapAddr = InitSectionMgrAndGetAddress();
51 
52     return heapAddr;
53 }
54 
InsertRTLog(MOS_OCA_RTLOG_COMPONENT_TPYE componentType,bool isErr,int32_t id,uint32_t paramCount,const void * param)55 MOS_STATUS OcaRtLogSectionMgr::InsertRTLog(
56     MOS_OCA_RTLOG_COMPONENT_TPYE componentType,
57     bool                         isErr,
58     int32_t                      id,
59     uint32_t                     paramCount,
60     const void                   *param)
61 {
62     //Try to init by calling GetMemAddress.
63     GetMemAddress();
64 
65     if (paramCount != MOS_OCA_RTLOG_MAX_PARAM_COUNT)
66     {
67         return MOS_STATUS_INVALID_PARAMETER;
68     }
69     if (componentType < MOS_OCA_RTLOG_COMPONENT_MAX)
70     {
71         OcaRtLogSectionMgr *insMgr = &s_rtLogSectionMgr[componentType];
72 
73         if (insMgr->IsInitialized())
74         {
75             uint64_t index = 0;
76             MosUtilities::MosQueryPerformanceCounter(&index);
77             MOS_OCA_RTLOG_HEADER header = {};
78             header.globalId             = index;
79             header.id                   = id;
80             header.paramCount           = paramCount;
81             MOS_OS_CHK_STATUS_RETURN(insMgr->InsertData(header, (uint8_t *)param));
82         }
83     }
84     return MOS_STATUS_SUCCESS;
85 }
86 
InitSectionMgrAndGetAddress()87 uint8_t *OcaRtLogSectionMgr::InitSectionMgrAndGetAddress()
88 {
89     uint64_t linearAddress = (uint64_t)s_localSysMem;
90 
91     uint8_t  *heapAddr     = (uint8_t *)((linearAddress + MOS_PAGE_SIZE - 1) & ADDRESS_PAGE_ALIGNMENT_MASK);
92 
93     uint32_t offset = 0;
94     uint32_t initeSize = MAX_OCA_RT_SUB_SIZE;
95     for (int i = 0; i < MOS_OCA_RTLOG_COMPONENT_MAX; ++i)
96     {
97         initeSize = (MOS_OCA_RTLOG_COMPONENT_TPYE)i == MOS_OCA_RTLOG_COMPONENT_COMMON ? MAX_OCA_RT_COMMON_SUB_SIZE : MAX_OCA_RT_SUB_SIZE;
98         s_rtLogSectionMgr[i].Init(heapAddr, MAX_OCA_RT_SIZE, initeSize, offset);
99         MOS_OCA_RTLOG_SECTION_HEADER sectionHeader = {};
100         sectionHeader.magicNum      = MOS_OCA_RTLOG_MAGIC_NUM;
101         sectionHeader.componentType = (MOS_OCA_RTLOG_COMPONENT_TPYE)i;
102         sectionHeader.freq          = 0;
103         MosUtilities::MosQueryPerformanceFrequency(&sectionHeader.freq);
104         s_rtLogSectionMgr[i].InsertUid(sectionHeader);
105         offset += ((MOS_OCA_RTLOG_COMPONENT_TPYE)i == MOS_OCA_RTLOG_COMPONENT_COMMON ? MAX_OCA_RT_COMMON_SUB_SIZE : MAX_OCA_RT_SUB_SIZE);
106     }
107     return heapAddr;
108 }
109 
Init(uint8_t * logSysMem,uint32_t size,uint32_t componentSize,uint32_t offset)110 void OcaRtLogSectionMgr::Init(uint8_t* logSysMem, uint32_t size, uint32_t componentSize, uint32_t offset)
111 {
112     if (logSysMem && size && componentSize)
113     {
114         m_LockedHeap = logSysMem;
115         m_HeapSize   = size;
116         m_Offset     = offset;
117         m_HeapHandle = -1;
118         m_EntryCount = (componentSize - sizeof(MOS_OCA_RTLOG_SECTION_HEADER))/ MOS_OCA_RTLOG_ENTRY_SIZE;
119 
120         m_IsInitialized = true;
121     }
122 }
123 
AllocHeapHandle()124 int32_t OcaRtLogSectionMgr::AllocHeapHandle()
125 {
126     return MosUtilities::MosAtomicIncrement(&m_HeapHandle);
127 }
128 
InsertUid(MOS_OCA_RTLOG_SECTION_HEADER sectionHeader)129 MOS_STATUS OcaRtLogSectionMgr::InsertUid(MOS_OCA_RTLOG_SECTION_HEADER sectionHeader)
130 {
131     if (0 == sectionHeader.magicNum)
132     {
133         return MOS_STATUS_INVALID_PARAMETER;
134     }
135     MOS_OS_CHK_STATUS_RETURN(MOS_SecureMemcpy((uint8_t *)m_LockedHeap + m_Offset, sizeof(MOS_OCA_RTLOG_SECTION_HEADER), &sectionHeader, sizeof(MOS_OCA_RTLOG_SECTION_HEADER)));
136     m_Offset += sizeof(MOS_OCA_RTLOG_SECTION_HEADER);
137     return MOS_STATUS_SUCCESS;
138 }
139 
InsertData(MOS_OCA_RTLOG_HEADER header,const void * param)140 MOS_STATUS OcaRtLogSectionMgr::InsertData(MOS_OCA_RTLOG_HEADER header, const void *param)
141 {
142     if (param)
143     {
144         if (header.paramCount * (sizeof(int32_t) + sizeof(int64_t)) > MOS_OCA_RTLOG_ENTRY_SIZE)
145         {
146             return MOS_STATUS_NO_SPACE;
147         }
148         int32_t heapHandle = AllocHeapHandle()%m_EntryCount;
149         if (heapHandle < m_EntryCount)
150         {
151             uint8_t *copyAddr = (uint8_t *)m_LockedHeap + m_Offset + heapHandle * MOS_OCA_RTLOG_ENTRY_SIZE;
152             MOS_OS_CHK_STATUS_RETURN(MOS_SecureMemcpy(copyAddr, sizeof(MOS_OCA_RTLOG_HEADER), &header, sizeof(MOS_OCA_RTLOG_HEADER)));
153             uint32_t copySize = header.paramCount * (sizeof(int32_t) + sizeof(int64_t));
154             MOS_OS_CHK_STATUS_RETURN(MOS_SecureMemcpy(copyAddr + sizeof(MOS_OCA_RTLOG_HEADER), copySize, param, copySize));
155         }
156     }
157     return MOS_STATUS_SUCCESS;
158 }