1b049dde5Sopenharmony_ci/*
2b049dde5Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3b049dde5Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4b049dde5Sopenharmony_ci *
5b049dde5Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
6b049dde5Sopenharmony_ci * are permitted provided that the following conditions are met:
7b049dde5Sopenharmony_ci *
8b049dde5Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
9b049dde5Sopenharmony_ci *    conditions and the following disclaimer.
10b049dde5Sopenharmony_ci *
11b049dde5Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12b049dde5Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
13b049dde5Sopenharmony_ci *    provided with the distribution.
14b049dde5Sopenharmony_ci *
15b049dde5Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16b049dde5Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
17b049dde5Sopenharmony_ci *    permission.
18b049dde5Sopenharmony_ci *
19b049dde5Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20b049dde5Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21b049dde5Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b049dde5Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23b049dde5Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24b049dde5Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25b049dde5Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26b049dde5Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27b049dde5Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28b049dde5Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29b049dde5Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30b049dde5Sopenharmony_ci */
31b049dde5Sopenharmony_ci
32b049dde5Sopenharmony_ci#include "hievent_driver.h"
33b049dde5Sopenharmony_ci
34b049dde5Sopenharmony_ci#include <assert.h>
35b049dde5Sopenharmony_ci#include <errno.h>
36b049dde5Sopenharmony_ci#include <fcntl.h>
37b049dde5Sopenharmony_ci#include <fs/driver.h>
38b049dde5Sopenharmony_ci#include <linux/list.h>
39b049dde5Sopenharmony_ci#include <linux/wait.h>
40b049dde5Sopenharmony_ci#include <semaphore.h>
41b049dde5Sopenharmony_ci#include <stdio.h>
42b049dde5Sopenharmony_ci#include <sys/types.h>
43b049dde5Sopenharmony_ci#include <unistd.h>
44b049dde5Sopenharmony_ci
45b049dde5Sopenharmony_ci#include "los_init.h"
46b049dde5Sopenharmony_ci#include "los_memory.h"
47b049dde5Sopenharmony_ci#include "los_mp.h"
48b049dde5Sopenharmony_ci#include "los_mux.h"
49b049dde5Sopenharmony_ci#include "los_process_pri.h"
50b049dde5Sopenharmony_ci#include "los_task_pri.h"
51b049dde5Sopenharmony_ci#include "los_vm_lock.h"
52b049dde5Sopenharmony_ci#include "los_vm_map.h"
53b049dde5Sopenharmony_ci#include "poll.h"
54b049dde5Sopenharmony_ci#include "user_copy.h"
55b049dde5Sopenharmony_ci
56b049dde5Sopenharmony_ci#define HIEVENT_LOG_BUFFER 1024
57b049dde5Sopenharmony_ci#define DRIVER_MODE 0666
58b049dde5Sopenharmony_ci
59b049dde5Sopenharmony_cistruct HieventEntry {
60b049dde5Sopenharmony_ci    uint16_t len;
61b049dde5Sopenharmony_ci    uint16_t hdrSize;
62b049dde5Sopenharmony_ci    int32_t pid;
63b049dde5Sopenharmony_ci    int32_t tid;
64b049dde5Sopenharmony_ci    int32_t sec;
65b049dde5Sopenharmony_ci    int32_t nsec;
66b049dde5Sopenharmony_ci    char msg[0];
67b049dde5Sopenharmony_ci};
68b049dde5Sopenharmony_ci
69b049dde5Sopenharmony_cistruct HieventCharDevice {
70b049dde5Sopenharmony_ci    int flag;
71b049dde5Sopenharmony_ci    LosMux mtx;
72b049dde5Sopenharmony_ci    unsigned char *buffer;
73b049dde5Sopenharmony_ci    wait_queue_head_t wq;
74b049dde5Sopenharmony_ci    size_t writeOffset;
75b049dde5Sopenharmony_ci    size_t headOffset;
76b049dde5Sopenharmony_ci    size_t size;
77b049dde5Sopenharmony_ci    size_t count;
78b049dde5Sopenharmony_ci} g_hieventDev;
79b049dde5Sopenharmony_ci
80b049dde5Sopenharmony_cistatic inline unsigned char *HieventBufferHead(void)
81b049dde5Sopenharmony_ci{
82b049dde5Sopenharmony_ci    if (g_hieventDev.headOffset > HIEVENT_LOG_BUFFER) {
83b049dde5Sopenharmony_ci        g_hieventDev.headOffset = g_hieventDev.headOffset % HIEVENT_LOG_BUFFER;
84b049dde5Sopenharmony_ci    }
85b049dde5Sopenharmony_ci    return g_hieventDev.buffer + g_hieventDev.headOffset;
86b049dde5Sopenharmony_ci}
87b049dde5Sopenharmony_ci
88b049dde5Sopenharmony_ciint HieventOpen(struct file *filep)
89b049dde5Sopenharmony_ci{
90b049dde5Sopenharmony_ci    (void)filep;
91b049dde5Sopenharmony_ci    return 0;
92b049dde5Sopenharmony_ci}
93b049dde5Sopenharmony_ci
94b049dde5Sopenharmony_ciint HieventClose(struct file *filep)
95b049dde5Sopenharmony_ci{
96b049dde5Sopenharmony_ci    (void)filep;
97b049dde5Sopenharmony_ci    return 0;
98b049dde5Sopenharmony_ci}
99b049dde5Sopenharmony_ci
100b049dde5Sopenharmony_cistatic void HieventBufferInc(size_t sz)
101b049dde5Sopenharmony_ci{
102b049dde5Sopenharmony_ci    if (g_hieventDev.size + sz <= HIEVENT_LOG_BUFFER) {
103b049dde5Sopenharmony_ci        g_hieventDev.size += sz;
104b049dde5Sopenharmony_ci        g_hieventDev.writeOffset += sz;
105b049dde5Sopenharmony_ci        g_hieventDev.writeOffset %= HIEVENT_LOG_BUFFER;
106b049dde5Sopenharmony_ci        g_hieventDev.count++;
107b049dde5Sopenharmony_ci    }
108b049dde5Sopenharmony_ci}
109b049dde5Sopenharmony_ci
110b049dde5Sopenharmony_cistatic void HieventBufferDec(size_t sz)
111b049dde5Sopenharmony_ci{
112b049dde5Sopenharmony_ci    if (g_hieventDev.size >= sz) {
113b049dde5Sopenharmony_ci        g_hieventDev.size -= sz;
114b049dde5Sopenharmony_ci        g_hieventDev.headOffset += sz;
115b049dde5Sopenharmony_ci        g_hieventDev.headOffset %= HIEVENT_LOG_BUFFER;
116b049dde5Sopenharmony_ci        g_hieventDev.count--;
117b049dde5Sopenharmony_ci    }
118b049dde5Sopenharmony_ci}
119b049dde5Sopenharmony_ci
120b049dde5Sopenharmony_cistatic int HieventBufferCopy(unsigned char *dst, unsigned dstLen,
121b049dde5Sopenharmony_ci                             unsigned char *src, size_t srcLen)
122b049dde5Sopenharmony_ci{
123b049dde5Sopenharmony_ci    int retval = -1;
124b049dde5Sopenharmony_ci
125b049dde5Sopenharmony_ci    size_t minLen = dstLen > srcLen ? srcLen : dstLen;
126b049dde5Sopenharmony_ci
127b049dde5Sopenharmony_ci    if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)dst, minLen) &&
128b049dde5Sopenharmony_ci        LOS_IsUserAddressRange((vaddr_t)(uintptr_t)src, minLen)) {
129b049dde5Sopenharmony_ci        return retval;
130b049dde5Sopenharmony_ci    }
131b049dde5Sopenharmony_ci
132b049dde5Sopenharmony_ci    if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)dst, minLen)) {
133b049dde5Sopenharmony_ci        retval = LOS_ArchCopyToUser(dst, src, minLen);
134b049dde5Sopenharmony_ci    } else if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)src, minLen)) {
135b049dde5Sopenharmony_ci        retval = LOS_ArchCopyFromUser(dst, src, minLen);
136b049dde5Sopenharmony_ci    } else {
137b049dde5Sopenharmony_ci        retval = memcpy_s(dst, dstLen, src, srcLen);
138b049dde5Sopenharmony_ci    }
139b049dde5Sopenharmony_ci    return retval;
140b049dde5Sopenharmony_ci}
141b049dde5Sopenharmony_ci
142b049dde5Sopenharmony_cistatic int HieventReadRingBuffer(unsigned char *buffer, size_t bufLen)
143b049dde5Sopenharmony_ci{
144b049dde5Sopenharmony_ci    int retval;
145b049dde5Sopenharmony_ci    size_t bufLeft = HIEVENT_LOG_BUFFER - g_hieventDev.headOffset;
146b049dde5Sopenharmony_ci    if (bufLeft > bufLen) {
147b049dde5Sopenharmony_ci        retval = HieventBufferCopy(buffer, bufLen, HieventBufferHead(), bufLen);
148b049dde5Sopenharmony_ci    } else {
149b049dde5Sopenharmony_ci        retval = HieventBufferCopy(buffer, bufLen, HieventBufferHead(), bufLeft);
150b049dde5Sopenharmony_ci        if (retval < 0) {
151b049dde5Sopenharmony_ci            return retval;
152b049dde5Sopenharmony_ci        }
153b049dde5Sopenharmony_ci
154b049dde5Sopenharmony_ci        retval = HieventBufferCopy(buffer + bufLeft, bufLen - bufLeft,
155b049dde5Sopenharmony_ci                                   g_hieventDev.buffer, bufLen - bufLeft);
156b049dde5Sopenharmony_ci    }
157b049dde5Sopenharmony_ci    return retval;
158b049dde5Sopenharmony_ci}
159b049dde5Sopenharmony_ci
160b049dde5Sopenharmony_cistatic ssize_t HieventRead(struct file *filep, char *buffer, size_t bufLen)
161b049dde5Sopenharmony_ci{
162b049dde5Sopenharmony_ci    ssize_t retval;
163b049dde5Sopenharmony_ci    struct HieventEntry header;
164b049dde5Sopenharmony_ci
165b049dde5Sopenharmony_ci    (void)filep;
166b049dde5Sopenharmony_ci
167b049dde5Sopenharmony_ci    wait_event_interruptible(g_hieventDev.wq, (g_hieventDev.size > 0));
168b049dde5Sopenharmony_ci
169b049dde5Sopenharmony_ci    (VOID)LOS_MuxAcquire(&g_hieventDev.mtx);
170b049dde5Sopenharmony_ci
171b049dde5Sopenharmony_ci    retval = HieventReadRingBuffer((unsigned char *)&header, sizeof(header));
172b049dde5Sopenharmony_ci    if (retval < 0) {
173b049dde5Sopenharmony_ci        retval = -EINVAL;
174b049dde5Sopenharmony_ci        goto out;
175b049dde5Sopenharmony_ci    }
176b049dde5Sopenharmony_ci
177b049dde5Sopenharmony_ci    if (bufLen < header.len + sizeof(header)) {
178b049dde5Sopenharmony_ci        PRINT_ERR("buffer too small\n");
179b049dde5Sopenharmony_ci        retval = -ENOMEM;
180b049dde5Sopenharmony_ci        goto out;
181b049dde5Sopenharmony_ci    }
182b049dde5Sopenharmony_ci
183b049dde5Sopenharmony_ci    HieventBufferDec(sizeof(header));
184b049dde5Sopenharmony_ci
185b049dde5Sopenharmony_ci    retval = HieventBufferCopy((unsigned char *)buffer, bufLen,
186b049dde5Sopenharmony_ci                               (unsigned char *)&header, sizeof(header));
187b049dde5Sopenharmony_ci    if (retval < 0) {
188b049dde5Sopenharmony_ci        retval = -EINVAL;
189b049dde5Sopenharmony_ci        goto out;
190b049dde5Sopenharmony_ci    }
191b049dde5Sopenharmony_ci
192b049dde5Sopenharmony_ci    retval = HieventReadRingBuffer((unsigned char *)(buffer + sizeof(header)),
193b049dde5Sopenharmony_ci                                   header.len);
194b049dde5Sopenharmony_ci    if (retval < 0) {
195b049dde5Sopenharmony_ci        retval = -EINVAL;
196b049dde5Sopenharmony_ci        goto out;
197b049dde5Sopenharmony_ci    }
198b049dde5Sopenharmony_ci
199b049dde5Sopenharmony_ci    HieventBufferDec(header.len);
200b049dde5Sopenharmony_ci
201b049dde5Sopenharmony_ci    retval = header.len + sizeof(header);
202b049dde5Sopenharmony_ciout:
203b049dde5Sopenharmony_ci    if (retval == -ENOMEM) {
204b049dde5Sopenharmony_ci        // clean ring buffer
205b049dde5Sopenharmony_ci        g_hieventDev.writeOffset = 0;
206b049dde5Sopenharmony_ci        g_hieventDev.headOffset = 0;
207b049dde5Sopenharmony_ci        g_hieventDev.size = 0;
208b049dde5Sopenharmony_ci        g_hieventDev.count = 0;
209b049dde5Sopenharmony_ci    }
210b049dde5Sopenharmony_ci    (VOID)LOS_MuxRelease(&g_hieventDev.mtx);
211b049dde5Sopenharmony_ci    return retval;
212b049dde5Sopenharmony_ci}
213b049dde5Sopenharmony_ci
214b049dde5Sopenharmony_cistatic int HieventWriteRingBuffer(unsigned char *buffer, size_t bufLen)
215b049dde5Sopenharmony_ci{
216b049dde5Sopenharmony_ci    int retval;
217b049dde5Sopenharmony_ci    size_t bufLeft = HIEVENT_LOG_BUFFER - g_hieventDev.writeOffset;
218b049dde5Sopenharmony_ci    if (bufLen > bufLeft) {
219b049dde5Sopenharmony_ci        retval = HieventBufferCopy(g_hieventDev.buffer + g_hieventDev.writeOffset,
220b049dde5Sopenharmony_ci                                   bufLeft, buffer, bufLeft);
221b049dde5Sopenharmony_ci        if (retval) {
222b049dde5Sopenharmony_ci            return -1;
223b049dde5Sopenharmony_ci        }
224b049dde5Sopenharmony_ci        retval = HieventBufferCopy(g_hieventDev.buffer, HIEVENT_LOG_BUFFER,
225b049dde5Sopenharmony_ci                                   buffer + bufLeft, bufLen - bufLeft);
226b049dde5Sopenharmony_ci    } else {
227b049dde5Sopenharmony_ci        retval = HieventBufferCopy(g_hieventDev.buffer + g_hieventDev.writeOffset,
228b049dde5Sopenharmony_ci                                   bufLeft, buffer, bufLen);
229b049dde5Sopenharmony_ci    }
230b049dde5Sopenharmony_ci    if (retval < 0) {
231b049dde5Sopenharmony_ci        return -1;
232b049dde5Sopenharmony_ci    }
233b049dde5Sopenharmony_ci    return 0;
234b049dde5Sopenharmony_ci}
235b049dde5Sopenharmony_ci
236b049dde5Sopenharmony_cistatic void HieventHeadInit(struct HieventEntry *header, size_t len)
237b049dde5Sopenharmony_ci{
238b049dde5Sopenharmony_ci    struct timespec now;
239b049dde5Sopenharmony_ci
240b049dde5Sopenharmony_ci    clock_gettime(CLOCK_REALTIME, &now);
241b049dde5Sopenharmony_ci
242b049dde5Sopenharmony_ci    header->len = len;
243b049dde5Sopenharmony_ci    header->pid = LOS_GetCurrProcessID();
244b049dde5Sopenharmony_ci    header->tid = 0;
245b049dde5Sopenharmony_ci    header->sec = now.tv_sec;
246b049dde5Sopenharmony_ci    header->nsec = now.tv_nsec;
247b049dde5Sopenharmony_ci    header->hdrSize = sizeof(struct HieventEntry);
248b049dde5Sopenharmony_ci}
249b049dde5Sopenharmony_ci
250b049dde5Sopenharmony_cistatic void HieventCoverOldLog(size_t bufLen)
251b049dde5Sopenharmony_ci{
252b049dde5Sopenharmony_ci    int retval;
253b049dde5Sopenharmony_ci    struct HieventEntry header;
254b049dde5Sopenharmony_ci    size_t totalSize = bufLen + sizeof(struct HieventEntry);
255b049dde5Sopenharmony_ci
256b049dde5Sopenharmony_ci    while (totalSize + g_hieventDev.size > HIEVENT_LOG_BUFFER) {
257b049dde5Sopenharmony_ci        retval = HieventReadRingBuffer((unsigned char *)&header, sizeof(header));
258b049dde5Sopenharmony_ci        if (retval < 0) {
259b049dde5Sopenharmony_ci            break;
260b049dde5Sopenharmony_ci        }
261b049dde5Sopenharmony_ci
262b049dde5Sopenharmony_ci        /* let count decrease twice */
263b049dde5Sopenharmony_ci        HieventBufferDec(sizeof(header));
264b049dde5Sopenharmony_ci        HieventBufferDec(header.len);
265b049dde5Sopenharmony_ci    }
266b049dde5Sopenharmony_ci}
267b049dde5Sopenharmony_ci
268b049dde5Sopenharmony_ciint HieventWriteInternal(const char *buffer, size_t bufLen)
269b049dde5Sopenharmony_ci{
270b049dde5Sopenharmony_ci    struct HieventEntry header;
271b049dde5Sopenharmony_ci    int retval;
272b049dde5Sopenharmony_ci
273b049dde5Sopenharmony_ci    if (bufLen < sizeof(int) ||
274b049dde5Sopenharmony_ci        bufLen > HIEVENT_LOG_BUFFER - sizeof(struct HieventEntry)) {
275b049dde5Sopenharmony_ci        return -EINVAL;
276b049dde5Sopenharmony_ci    }
277b049dde5Sopenharmony_ci
278b049dde5Sopenharmony_ci    (VOID)LOS_MuxAcquire(&g_hieventDev.mtx);
279b049dde5Sopenharmony_ci
280b049dde5Sopenharmony_ci    /* need userspace use writev */
281b049dde5Sopenharmony_ci    if (LOS_IsUserAddressRange((vaddr_t)(uintptr_t)buffer, bufLen)) {
282b049dde5Sopenharmony_ci        retval = -EINVAL;
283b049dde5Sopenharmony_ci        goto out;
284b049dde5Sopenharmony_ci    }
285b049dde5Sopenharmony_ci
286b049dde5Sopenharmony_ci    int checkCode = *((int *)buffer);
287b049dde5Sopenharmony_ci
288b049dde5Sopenharmony_ci    if (checkCode != CHECK_CODE) {
289b049dde5Sopenharmony_ci        retval = -EINVAL;
290b049dde5Sopenharmony_ci        goto out;
291b049dde5Sopenharmony_ci    }
292b049dde5Sopenharmony_ci
293b049dde5Sopenharmony_ci    HieventCoverOldLog(bufLen);
294b049dde5Sopenharmony_ci
295b049dde5Sopenharmony_ci    HieventHeadInit(&header, bufLen - sizeof(int));
296b049dde5Sopenharmony_ci
297b049dde5Sopenharmony_ci    retval = HieventWriteRingBuffer((unsigned char *)&header, sizeof(header));
298b049dde5Sopenharmony_ci    if (retval) {
299b049dde5Sopenharmony_ci        retval = -EINVAL;
300b049dde5Sopenharmony_ci        goto out;
301b049dde5Sopenharmony_ci    }
302b049dde5Sopenharmony_ci    HieventBufferInc(sizeof(header));
303b049dde5Sopenharmony_ci
304b049dde5Sopenharmony_ci    retval = HieventWriteRingBuffer((unsigned char *)(buffer + sizeof(int)),
305b049dde5Sopenharmony_ci                                    header.len);
306b049dde5Sopenharmony_ci    if (retval) {
307b049dde5Sopenharmony_ci        retval = -EINVAL;
308b049dde5Sopenharmony_ci        goto out;
309b049dde5Sopenharmony_ci    }
310b049dde5Sopenharmony_ci
311b049dde5Sopenharmony_ci    HieventBufferInc(header.len);
312b049dde5Sopenharmony_ci
313b049dde5Sopenharmony_ci    retval = header.len;
314b049dde5Sopenharmony_ci
315b049dde5Sopenharmony_ciout:
316b049dde5Sopenharmony_ci    (VOID)LOS_MuxRelease(&g_hieventDev.mtx);
317b049dde5Sopenharmony_ci    if (retval > 0) {
318b049dde5Sopenharmony_ci        wake_up_interruptible(&g_hieventDev.wq);
319b049dde5Sopenharmony_ci    }
320b049dde5Sopenharmony_ci    return retval;
321b049dde5Sopenharmony_ci}
322b049dde5Sopenharmony_ci
323b049dde5Sopenharmony_cistatic ssize_t HieventWrite(struct file *filep,
324b049dde5Sopenharmony_ci                            const char *buffer, size_t bufLen)
325b049dde5Sopenharmony_ci{
326b049dde5Sopenharmony_ci    (void)filep;
327b049dde5Sopenharmony_ci    return HieventWriteInternal(buffer, bufLen);
328b049dde5Sopenharmony_ci}
329b049dde5Sopenharmony_ci
330b049dde5Sopenharmony_cistatic int HieventPoll(struct file *filep, poll_table *fds)
331b049dde5Sopenharmony_ci{
332b049dde5Sopenharmony_ci    (void)filep;
333b049dde5Sopenharmony_ci
334b049dde5Sopenharmony_ci    wait_event_interruptible(g_hieventDev.wq, (g_hieventDev.size > 0));
335b049dde5Sopenharmony_ci
336b049dde5Sopenharmony_ci    return (POLLOUT | POLLWRNORM);
337b049dde5Sopenharmony_ci}
338b049dde5Sopenharmony_ci
339b049dde5Sopenharmony_cistatic int HieventIoctl(struct file *filep, int cmd, unsigned long arg)
340b049dde5Sopenharmony_ci{
341b049dde5Sopenharmony_ci    // not support ioctl in liteos now
342b049dde5Sopenharmony_ci    (void)filep;
343b049dde5Sopenharmony_ci    (void)cmd;
344b049dde5Sopenharmony_ci    (void)arg;
345b049dde5Sopenharmony_ci    return 0;
346b049dde5Sopenharmony_ci}
347b049dde5Sopenharmony_ci
348b049dde5Sopenharmony_cistatic struct file_operations_vfs g_hieventFops = {
349b049dde5Sopenharmony_ci    .open  = HieventOpen,   /* open */
350b049dde5Sopenharmony_ci    .close = HieventClose,  /* close */
351b049dde5Sopenharmony_ci    .read  = HieventRead,   /* read */
352b049dde5Sopenharmony_ci    .write = HieventWrite,  /* write */
353b049dde5Sopenharmony_ci    .seek  = NULL,          /* seek */
354b049dde5Sopenharmony_ci    .ioctl = HieventIoctl,  /* ioctl */
355b049dde5Sopenharmony_ci    .mmap  = NULL,          /* mmap */
356b049dde5Sopenharmony_ci    .poll  = HieventPoll,   /* poll */
357b049dde5Sopenharmony_ci};
358b049dde5Sopenharmony_ci
359b049dde5Sopenharmony_cistatic int HieventDeviceInit(void)
360b049dde5Sopenharmony_ci{
361b049dde5Sopenharmony_ci    g_hieventDev.buffer = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR,
362b049dde5Sopenharmony_ci                                       HIEVENT_LOG_BUFFER);
363b049dde5Sopenharmony_ci    if (g_hieventDev.buffer == NULL) {
364b049dde5Sopenharmony_ci        return -ENOMEM;
365b049dde5Sopenharmony_ci    }
366b049dde5Sopenharmony_ci
367b049dde5Sopenharmony_ci    init_waitqueue_head(&g_hieventDev.wq);
368b049dde5Sopenharmony_ci    (void)LOS_MuxInit(&g_hieventDev.mtx, NULL);
369b049dde5Sopenharmony_ci
370b049dde5Sopenharmony_ci    g_hieventDev.writeOffset = 0;
371b049dde5Sopenharmony_ci    g_hieventDev.headOffset = 0;
372b049dde5Sopenharmony_ci    g_hieventDev.size = 0;
373b049dde5Sopenharmony_ci    g_hieventDev.count = 0;
374b049dde5Sopenharmony_ci    return 0;
375b049dde5Sopenharmony_ci}
376b049dde5Sopenharmony_ci
377b049dde5Sopenharmony_ciint HieventInit(void)
378b049dde5Sopenharmony_ci{
379b049dde5Sopenharmony_ci    int ret = HieventDeviceInit();
380b049dde5Sopenharmony_ci    if (ret != 0) {
381b049dde5Sopenharmony_ci        return ret;
382b049dde5Sopenharmony_ci    }
383b049dde5Sopenharmony_ci
384b049dde5Sopenharmony_ci    register_driver("/dev/hwlog_exception", &g_hieventFops,
385b049dde5Sopenharmony_ci                    DRIVER_MODE, &g_hieventDev);
386b049dde5Sopenharmony_ci    return 0;
387b049dde5Sopenharmony_ci}
388b049dde5Sopenharmony_ci
389b049dde5Sopenharmony_ciLOS_MODULE_INIT(HieventInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
390