aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra/unix-misc.c
blob: 54016ed74f4dc4c1c3330cab3da83dc930db410c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
  Copyright (c) 2005 Eliot Dresselhaus

  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 <vppinfra/error.h>
#include <vppinfra/os.h>
#include <vppinfra/unix.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>		/* writev */
#include <fcntl.h>
#include <stdio.h>		/* for sprintf */

__thread uword __os_thread_index = 0;
__thread uword __os_numa_index = 0;

clib_error_t *
clib_file_n_bytes (char *file, uword * result)
{
  struct stat s;

  if (stat (file, &s) < 0)
    return clib_error_return_unix (0, "stat `%s'", file);

  if (S_ISREG (s.st_mode))
    *result = s.st_size;
  else
    *result = 0;

  return /* no error */ 0;
}

clib_error_t *
clib_file_read_contents (char *file, u8 * result, uword n_bytes)
{
  int fd = -1;
  uword n_done, n_left;
  clib_error_t *error = 0;
  u8 *v = result;

  if ((fd = open (file, 0)) < 0)
    return clib_error_return_unix (0, "open `%s'", file);

  n_left = n_bytes;
  n_done = 0;
  while (n_left > 0)
    {
      int n_read;
      if ((n_read = read (fd, v + n_done, n_left)) < 0)
	{
	  error = clib_error_return_unix (0, "open `%s'", file);
	  goto done;
	}

      /* End of file. */
      if (n_read == 0)
	break;

      n_left -= n_read;
      n_done += n_read;
    }

  if (n_left > 0)
    {
      error =
	clib_error_return (0,
			   " `%s' expected to read %wd bytes; read only %wd",
			   file, n_bytes, n_bytes - n_left);
      goto done;
    }

done:
  close (fd);
  return error;
}

clib_error_t *
clib_file_contents (char *file, u8 ** result)
{
  uword n_bytes;
  clib_error_t *error = 0;
  u8 *v;

  if ((error = clib_file_n_bytes (file, &n_bytes)))
    return error;

  v = 0;
  vec_resize (v, n_bytes);

  error = clib_file_read_contents (file, v, n_bytes);

  if (error)
    vec_free (v);
  else
    *result = v;

  return error;
}

clib_error_t *
unix_proc_file_contents (char *file, u8 ** result)
{
  u8 *rv = 0;
  uword pos;
  int bytes, fd;

  /* Unfortunately, stat(/proc/XXX) returns zero... */
  fd = open (file, O_RDONLY);

  if (fd < 0)
    return clib_error_return_unix (0, "open `%s'", file);

  vec_validate (rv, 4095);
  pos = 0;
  while (1)
    {
      bytes = read (fd, rv + pos, 4096);
      if (bytes < 0)
	{
	  close (fd);
	  vec_free (rv);
	  return clib_error_return_unix (0, "read '%s'", file);
	}

      if (bytes == 0)
	{
	  _vec_len (rv) = pos;
	  break;
	}
      pos += bytes;
      vec_validate (rv, pos + 4095);
    }
  *result = rv;
  close (fd);
  return 0;
}

void os_panic (void) __attribute__ ((weak));

void
os_panic (void)
{
  abort ();
}

void os_exit (int) __attribute__ ((weak));

void
os_exit (int code)
{
  exit (code);
}

void os_puts (u8 * string, uword string_length, uword is_error)
  __attribute__ ((weak));

void
os_puts (u8 * string, uword string_length, uword is_error)
{
  int cpu = os_get_thread_index ();
  int nthreads = os_get_nthreads ();
  char buf[64];
  int fd = is_error ? 2 : 1;
  struct iovec iovs[2];
  int n_iovs = 0;

  if (nthreads > 1)
    {
      snprintf (buf, sizeof (buf), "%d: ", cpu);

      iovs[n_iovs].iov_base = buf;
      iovs[n_iovs].iov_len = strlen (buf);
      n_iovs++;
    }

  iovs[n_iovs].iov_base = string;
  iovs[n_iovs].iov_len = string_length;
  n_iovs++;

  if (writev (fd, iovs, n_iovs) < 0)
    ;
}

void os_out_of_memory (void) __attribute__ ((weak));
void
os_out_of_memory (void)
{
  os_panic ();
}

uword os_get_nthreads (void) __attribute__ ((weak));
uword
os_get_nthreads (void)
{
  return 1;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
type order */ #define OSAL_LIST_FOR_EACH_ENTRY(entry, list, field, type) \ for (entry = OSAL_LIST_FIRST_ENTRY(list, type, field); \ entry; \ entry = OSAL_LIST_NEXT(entry, field, type)) #define OSAL_LIST_FOR_EACH_ENTRY_SAFE(entry, tmp_entry, list, field, type) \ for (entry = OSAL_LIST_FIRST_ENTRY(list, type, field), \ tmp_entry = (entry) ? OSAL_LIST_NEXT(entry, field, type) : NULL; \ entry != NULL; \ entry = (type *)tmp_entry, \ tmp_entry = (entry) ? OSAL_LIST_NEXT(entry, field, type) : NULL) /* TODO: OSAL_LIST_INSERT_ENTRY_AFTER */ #define OSAL_LIST_INSERT_ENTRY_AFTER(new_entry, entry, list) \ OSAL_LIST_PUSH_HEAD(new_entry, list) /* PCI config space */ #define OSAL_PCI_READ_CONFIG_BYTE(dev, address, dst) nothing #define OSAL_PCI_READ_CONFIG_WORD(dev, address, dst) nothing #define OSAL_PCI_READ_CONFIG_DWORD(dev, address, dst) nothing #define OSAL_PCI_FIND_EXT_CAPABILITY(dev, pcie_id) 0 #define OSAL_PCI_FIND_CAPABILITY(dev, pcie_id) 0 #define OSAL_PCI_WRITE_CONFIG_WORD(dev, address, val) nothing #define OSAL_BAR_SIZE(dev, bar_id) 0 /* Barriers */ #define OSAL_MMIOWB(dev) rte_wmb() #define OSAL_BARRIER(dev) rte_compiler_barrier() #define OSAL_SMP_RMB(dev) rte_rmb() #define OSAL_SMP_WMB(dev) rte_wmb() #define OSAL_RMB(dev) rte_rmb() #define OSAL_WMB(dev) rte_wmb() #define OSAL_DMA_SYNC(dev, addr, length, is_post) nothing #define OSAL_BIT(nr) (1UL << (nr)) #define OSAL_BITS_PER_BYTE (8) #define OSAL_BITS_PER_UL (sizeof(unsigned long) * OSAL_BITS_PER_BYTE) #define OSAL_BITS_PER_UL_MASK (OSAL_BITS_PER_UL - 1) /* Bitops */ void qede_set_bit(u32, unsigned long *); #define OSAL_SET_BIT(bit, bitmap) \ qede_set_bit(bit, bitmap) void qede_clr_bit(u32, unsigned long *); #define OSAL_CLEAR_BIT(bit, bitmap) \ qede_clr_bit(bit, bitmap) bool qede_test_bit(u32, unsigned long *); #define OSAL_TEST_BIT(bit, bitmap) \ qede_test_bit(bit, bitmap) u32 qede_find_first_bit(unsigned long *, u32); #define OSAL_FIND_FIRST_BIT(bitmap, length) \ qede_find_first_bit(bitmap, length) u32 qede_find_first_zero_bit(unsigned long *, u32); #define OSAL_FIND_FIRST_ZERO_BIT(bitmap, length) \ qede_find_first_zero_bit(bitmap, length) #define OSAL_BUILD_BUG_ON(cond) nothing #define ETH_ALEN ETHER_ADDR_LEN #define OSAL_BITMAP_WEIGHT(bitmap, count) 0 #define OSAL_LINK_UPDATE(hwfn) qed_link_update(hwfn) #define OSAL_TRANSCEIVER_UPDATE(hwfn) nothing #define OSAL_DCBX_AEN(hwfn, mib_type) nothing /* SR-IOV channel */ #define OSAL_VF_FLR_UPDATE(hwfn) nothing #define OSAL_VF_SEND_MSG2PF(dev, done, msg, reply_addr, msg_size, reply_size) 0 #define OSAL_VF_CQE_COMPLETION(_dev_p, _cqe, _protocol) (0) #define OSAL_PF_VF_MSG(hwfn, vfid) 0 #define OSAL_PF_VF_MALICIOUS(hwfn, vfid) nothing #define OSAL_IOV_CHK_UCAST(hwfn, vfid, params) 0 #define OSAL_IOV_POST_START_VPORT(hwfn, vf, vport_id, opaque_fid) nothing #define OSAL_IOV_VF_ACQUIRE(hwfn, vfid) 0 #define OSAL_IOV_VF_CLEANUP(hwfn, vfid) nothing #define OSAL_IOV_VF_VPORT_UPDATE(hwfn, vfid, p_params, p_mask) 0 #define OSAL_VF_UPDATE_ACQUIRE_RESC_RESP(_dev_p, _resc_resp) 0 #define OSAL_IOV_GET_OS_TYPE() 0 #define OSAL_IOV_VF_MSG_TYPE(hwfn, vfid, vf_msg_type) nothing #define OSAL_IOV_PF_RESP_TYPE(hwfn, vfid, pf_resp_type) nothing #define OSAL_IOV_VF_VPORT_STOP(hwfn, vf) nothing u32 qede_unzip_data(struct ecore_hwfn *p_hwfn, u32 input_len, u8 *input_buf, u32 max_size, u8 *unzip_buf); void qede_vf_fill_driver_data(struct ecore_hwfn *, struct vf_pf_resc_request *, struct ecore_vf_acquire_sw_info *); void qede_hw_err_notify(struct ecore_hwfn *p_hwfn, enum ecore_hw_err_type err_type); #define OSAL_VF_FILL_ACQUIRE_RESC_REQ(_dev_p, _resc_req, _os_info) \ qede_vf_fill_driver_data(_dev_p, _resc_req, _os_info) #define OSAL_UNZIP_DATA(p_hwfn, input_len, buf, max_size, unzip_buf) \ qede_unzip_data(p_hwfn, input_len, buf, max_size, unzip_buf) /* TODO: */ #define OSAL_SCHEDULE_RECOVERY_HANDLER(hwfn) nothing #define OSAL_HW_ERROR_OCCURRED(hwfn, err_type) \ qede_hw_err_notify(hwfn, err_type) #define OSAL_NVM_IS_ACCESS_ENABLED(hwfn) (1) #define OSAL_NUM_CPUS() 0 /* Utility functions */ #define RTE_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define DIV_ROUND_UP(size, to_what) RTE_DIV_ROUND_UP(size, to_what) #define RTE_ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) #define ROUNDUP(value, to_what) RTE_ROUNDUP((value), (to_what)) unsigned long qede_log2_align(unsigned long n); #define OSAL_ROUNDUP_POW_OF_TWO(val) \ qede_log2_align(val) u32 qede_osal_log2(u32); #define OSAL_LOG2(val) \ qede_osal_log2(val) #define PRINT(format, ...) printf #define PRINT_ERR(format, ...) PRINT #define OFFSETOF(str, field) __builtin_offsetof(str, field) #define OSAL_ASSERT(is_assert) assert(is_assert) #define OSAL_BEFORE_PF_START(file, engine) nothing #define OSAL_AFTER_PF_STOP(file, engine) nothing /* Endian macros */ #define OSAL_CPU_TO_BE32(val) rte_cpu_to_be_32(val) #define OSAL_BE32_TO_CPU(val) rte_be_to_cpu_32(val) #define OSAL_CPU_TO_LE32(val) rte_cpu_to_le_32(val) #define OSAL_CPU_TO_LE16(val) rte_cpu_to_le_16(val) #define OSAL_LE32_TO_CPU(val) rte_le_to_cpu_32(val) #define OSAL_LE16_TO_CPU(val) rte_le_to_cpu_16(val) #define OSAL_CPU_TO_BE64(val) rte_cpu_to_be_64(val) #define OSAL_ARRAY_SIZE(arr) RTE_DIM(arr) #define OSAL_SPRINTF(name, pattern, ...) \ sprintf(name, pattern, ##__VA_ARGS__) #define OSAL_SNPRINTF(buf, size, format, ...) \ snprintf(buf, size, format, ##__VA_ARGS__) #define OSAL_STRLEN(string) strlen(string) #define OSAL_STRCPY(dst, string) strcpy(dst, string) #define OSAL_STRNCPY(dst, string, len) strncpy(dst, string, len) #define OSAL_STRCMP(str1, str2) strcmp(str1, str2) #define OSAL_STRTOUL(str, base, res) 0 #define OSAL_INLINE inline #define OSAL_REG_ADDR(_p_hwfn, _offset) \ (void *)((u8 *)(uintptr_t)(_p_hwfn->regview) + (_offset)) #define OSAL_PAGE_SIZE 4096 #define OSAL_CACHE_LINE_SIZE RTE_CACHE_LINE_SIZE #define OSAL_IOMEM volatile #define OSAL_UNUSED __attribute__((unused)) #define OSAL_UNLIKELY(x) __builtin_expect(!!(x), 0) #define OSAL_MIN_T(type, __min1, __min2) \ ((type)(__min1) < (type)(__min2) ? (type)(__min1) : (type)(__min2)) #define OSAL_MAX_T(type, __max1, __max2) \ ((type)(__max1) > (type)(__max2) ? (type)(__max1) : (type)(__max2)) void qede_get_mcp_proto_stats(struct ecore_dev *, enum ecore_mcp_protocol_type, union ecore_mcp_protocol_stats *); #define OSAL_GET_PROTOCOL_STATS(dev, type, stats) \ qede_get_mcp_proto_stats(dev, type, stats) #define OSAL_SLOWPATH_IRQ_REQ(p_hwfn) (0) u32 qede_crc32(u32 crc, u8 *ptr, u32 length); #define OSAL_CRC32(crc, buf, length) qede_crc32(crc, buf, length) #define OSAL_CRC8_POPULATE(table, polynomial) nothing #define OSAL_CRC8(table, pdata, nbytes, crc) 0 #define OSAL_MFW_TLV_REQ(p_hwfn) nothing #define OSAL_MFW_FILL_TLV_DATA(type, buf, data) (0) #define OSAL_MFW_CMD_PREEMPT(p_hwfn) nothing #define OSAL_PF_VALIDATE_MODIFY_TUNN_CONFIG(p_hwfn, mask, b_update, tunn) 0 #define OSAL_DIV_S64(a, b) ((a) / (b)) #define OSAL_LLDP_RX_TLVS(p_hwfn, tlv_buf, tlv_size) nothing #endif /* __BCM_OSAL_H */