Updated `README.md` with instructions for building/using the kernel module.
[xeon-phi-kernel-module] / include / mic / ringbuffer.h
CommitLineData
800f879a
AT
1/*
2 * Copyright 2010-2017 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * Disclaimer: The codes contained in these modules may be specific to
14 * the Intel Software Development Platform codenamed Knights Ferry,
15 * and the Intel product codenamed Knights Corner, and are not backward
16 * compatible with other Intel products. Additionally, Intel will NOT
17 * support the codes or instruction set in future products.
18 *
19 * Intel offers no warranty of any kind regarding the code. This code is
20 * licensed on an "AS IS" basis and Intel is not obligated to provide
21 * any support, assistance, installation, training, or other services
22 * of any kind. Intel is also not obligated to provide any updates,
23 * enhancements or extensions. Intel specifically disclaims any warranty
24 * of merchantability, non-infringement, fitness for any particular
25 * purpose, and any other warranty.
26 *
27 * Further, Intel disclaims all liability of any kind, including but
28 * not limited to liability for infringement of any proprietary rights,
29 * relating to the use of the code, even if Intel is notified of the
30 * possibility of such liability. Except as expressly stated in an Intel
31 * license agreement provided with this code and agreed upon with Intel,
32 * no license, express or implied, by estoppel or otherwise, to any
33 * intellectual property rights is granted herein.
34 */
35
36/*
37Description: This is a generic ring buffer implementation to be used by
38anyone who needs a ring buffer. The ring buffer is maipulated
39using Read and Write functions. These functions perform all of
40the necessary space checks and only complete the operation if
41if the requested number of items can be read or written. A
42return value of false indicates that either the ring buffer
43contains less then the requested number of items (for Read) or
44there isn't enough space left in the ring buffer (for Write).
45*/
46
47#ifndef _MICHOST_RING_BUFFER_DEFINE
48
49#define _MICHOST_RING_BUFFER_DEFINE
50
51//
52// Requirements:
53// Ring base should be already aligned properly
54// Ring size should be just multiple of the alignment size
55// All packets should be at least multiple of 4 bytes for the purpose of padding
56//
57
58#define RINGBUFFER_ALIGNMENT_SIZE 64 // in byte
59
60typedef struct _ringbuffer
61{
62 uint8_t *ringbuff_ptr;
63 volatile uint32_t *readptr; // Points to the read offset
64 volatile uint32_t *writeptr; // Points to the write offset
65 uint32_t ringbuffsize;
66 uint32_t curr_readoffset; // cache it to improve performance.
67 uint32_t curr_writeoffset; // cache it to improve performance.
68 uint32_t old_readoffset;
69 uint32_t old_writeoffset;
70} ringbuffer;
71
72// Commands common across all ring buffers
73typedef enum _rb_cmdopcode
74{
75 // note: don't use 0, because the ring buffer
76 // is initialized to a bunch of 0's that aren't really commands.
77 MIC_RBCT_ERROR = 0x0, // an error has occurred if encountered
78 MIC_RBCT_NOP, // Used to skip empty space in the ringbuffer.
79 MIC_RBCT_DMAEXEC, // DMA buffer to transfer/execute
80 MIC_RBCT_SHUTDOWN, // bus power-down eminent
81 MIC_RBCT_CREATESTDPROCESS, // Launches an executable on the ramdisk.
82 MIC_RBCT_CREATENATIVEPROCESS, // Launches a native process.
83 // NRFIX : not implemented. If native apps are launched by loading shared
84 // libraries(DLLs) into a standard stub app then this command goes away.
85 MIC_RBCT_DESTROYPROCESS, // Destroys a process.
86 MIC_RBCT_VIRTUALALLOC, // Creates a uOS virtual address range
87 MIC_RBCT_MAPHOSTMEMORY, // Used by implement host kernel mode driver services
88 MIC_RBCT_UNMAPHOSTMEMORY, // Unmaps host memory
89 MIC_RBCT_UOSESCAPE, // Used to pass uOS escapes from the host
90 MIC_RBCT_RESERVED1, // Reserved for future use
91 MIC_RBCT_RESERVED2, // Reserved for future use
92 MIC_RBCT_UPLOADSTDAPPLICATION, // Uploads a standard application to the uOS
93 MIC_RBCT_CREATEUOSRESOURCE, // Creates a DPT page cache
94 MIC_RBCT_DESTROYUOSRESOURCE, // Destroys a DPT page cache
95 MIC_RBCT_RESERVE_RING_BANDWIDTH_DBOX_TRAFFIC, // Reserves a ring bandwidth for DBOX traffic
96
97 // Following commands are from MIC->Host (CRBT => CPU ring buffer.)
98 MIC_CRBT_LOG_INFO, // Host logs information sent by the uOS.
99
100 // Always make these the last ones in the list
101#if defined(MIC_DEBUG) || defined(ENABLE_GFXDEBUG)
102 MIC_RBCT_READPHYSICALMEMORY = 0x8000, // Used by debug tools to read memory on the device
103 MIC_RBCT_WRITEPHYSICALMEMORY, // Used by debug tools to write memory on the device
104#endif // defined(MIC_DEBUG) || defined(ENABLE_GFXDEBUG)
105 MIC_RBCT_CMD_MAX // No valid OpCodes above this one
106}ringbuff_cmdop;
107
108typedef struct _ringbuff_cmdhdr
109{
110 ringbuff_cmdop opcode:16;
111 uint32_t size:16;
112}ringbuff_cmdhdr;
113
114#ifdef __cplusplus
115extern "C" {
116#endif
117
118//---------------------------------
119// methods used by both
120//---------------------------------
121// initialize cached ring buffer structure
122void rb_initialize(ringbuffer* ringbuff, volatile uint32_t* readptr,
123 volatile uint32_t* writeptr, void *buff, const uint32_t size);
124
125//---------------------------------
126// writer-only methods
127//---------------------------------
128// write a new command. Must follow with fence/MMIO, then RingBufferCommit()
129int rb_write(ringbuffer* ringbuff, ringbuff_cmdhdr* cmd_header);
130// After write(), do an mfence(), an MMIO write to serialize, then Commit()
131void rb_commit(ringbuffer* ringbuff);
132// used on power state change to reset cached pointers
133void rb_reset(ringbuffer* ringbuff);
134// used to determine the largest possible command that could be sent next
135uint32_t rb_get_available_space(ringbuffer* ringbuff);
136
137// TODO: It may be more optimal to have "Reserve" function exposed to the client
138// instead of requiring it to create a command that will be copied into the ring buffer.
139
140
141//---------------------------------
142// reader-only methods
143//---------------------------------
144// uses (updates) the cached read pointer to get the next command, so writer doesn't
145// see the command as consumed
146ringbuff_cmdhdr* rb_get_next_cmd(ringbuffer* ringbuff);
147// updates the control block read pointer, which will be visible to the writer so it
148// can re-use the space
149void rb_update_readptr(ringbuffer* ringbuff, ringbuff_cmdhdr* cmd_header);
150// reader skips all commands, updating its next read offset
151void rb_skip_to_offset(ringbuffer* ringbuff, uint32_t new_readptr);
152
153// uOS used this method to determine if RingBuffer is empty or not before attempting
154// to fetch command out of ring buffer If ringbuffer is empty, means uOS would have
155// fetched it earlier.
156uint32_t rb_empty(ringbuffer* ringbuff);
157
158// only used by host simulator
159void rb_sync(ringbuffer* ringbuff);
160
161#ifdef __cplusplus
162}
163#endif
164
165#ifdef __LINUX_GPL__
166//==============================================================================
167// FUNCTION: AlignLow
168//
169// DESCRIPTION: Returns trunk(in_data / in_granularity) * in_granularity
170//
171// PARAMETERS:
172// in_data - Data to be aligned
173// in_granularity - Alignment chunk size - must be a power of 2
174#if defined(__cplusplus)
175template <typename TData>
176#else // no C++
177#define TData uint64_t
178#endif // if C++
179
180static inline TData AlignLow(TData in_data, uintptr_t in_granularity)
181{
182 TData mask = (TData)(in_granularity-1); // 64 -> 0x3f
183
184 // floor to granularity
185 TData low = in_data & ~mask;
186
187 return low;
188}
189
190#if !defined(__cplusplus)
191#undef TData
192#endif // if no C++
193#endif // __LINUX_GPL_
194
195#endif //_MICHOST_RING_BUFFER_DEFINE