1 /*
2  * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * @file	linux/sys.h
9  * @brief	Linux system primitives for libmetal.
10  */
11 
12 #ifndef __METAL_SYS__H__
13 #error "Include metal/sys.h instead of metal/linux/sys.h"
14 #endif
15 
16 #ifndef __METAL_LINUX_SYS__H__
17 #define __METAL_LINUX_SYS__H__
18 
19 #include <fcntl.h>
20 #include <libgen.h>
21 #include <limits.h>
22 #include <metal/cpu.h>
23 #include <metal/errno.h>
24 #include <pthread.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <syslog.h>
29 #include <sys/file.h>
30 #include <sys/mman.h>
31 #include <sys/stat.h>
32 #include <sys/syscall.h>
33 #include <sys/types.h>
34 #include <sys/wait.h>
35 #include <unistd.h>
36 
37 #include <linux/futex.h>
38 #include <sysfs/libsysfs.h>
39 #ifdef HAVE_HUGETLBFS_H
40 #include <hugetlbfs.h>
41 #endif
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 #define METAL_INVALID_VADDR     NULL
48 #define MAX_PAGE_SIZES		32
49 
50 #define metal_yield() metal_cpu_yield()
51 
52 struct metal_device;
53 
54 /** Structure of shared page or hugepage sized data. */
55 struct metal_page_size {
56 	/** Page size. */
57 	size_t	page_size;
58 
59 	/** Page shift. */
60 	unsigned long page_shift;
61 
62 	/** Path to hugetlbfs (or tmpfs) mount point. */
63 	char path[PATH_MAX];
64 
65 	/** Flags to use for mmap. */
66 	int mmap_flags;
67 };
68 
69 /** Structure of linux specific libmetal runtime state. */
70 struct metal_state {
71 
72 	/** Common (system independent) data. */
73 	struct metal_common_state common;
74 
75 	/** file descriptor for shared data. */
76 	int			data_fd;
77 
78 	/** system page size. */
79 	unsigned long		page_size;
80 
81 	/** system page shift. */
82 	unsigned long		page_shift;
83 
84 	/** sysfs mount point. */
85 	const char		*tmp_path;
86 
87 	/** available page sizes. */
88 	struct metal_page_size	page_sizes[MAX_PAGE_SIZES];
89 
90 	/** number of available page sizes. */
91 	int			num_page_sizes;
92 
93 	/** File descriptor for /proc/self/pagemap (or -1). */
94 	int			pagemap_fd;
95 };
96 
97 #ifdef METAL_INTERNAL
98 int metal_linux_bus_init(void);
99 void metal_linux_bus_finish(void);
100 
101 int metal_open(const char *path, int shm);
102 
103 int metal_map(int fd, off_t offset, size_t size, int expand,
104 	      int flags, void **result);
105 int metal_unmap(void *mem, size_t size);
106 
107 /**
108  * @brief	Read a device tree property of a device
109  *
110  * @param[in]	device metal_device of the intended DT node
111  * @param[in]	property_name name of the property to be read
112  * @param[out]	output output buffer to store read data
113  * @param[in]	len number of bytes to be read
114  * @return	0 on success, or -errno on error.
115  */
116 int metal_linux_get_device_property(struct metal_device *device,
117 				    const char *property_name,
118 				    void *output, int len);
119 
120 #define metal_for_each_page_size_up(ps)					\
121 	for ((ps) = &_metal.page_sizes[0];				\
122 	     (ps) <= &_metal.page_sizes[_metal.num_page_sizes - 1];	\
123 	     (ps)++)
124 
125 #define metal_for_each_page_size_down(ps)				\
126 	for ((ps) = &_metal.page_sizes[_metal.num_page_sizes - 1];	\
127 	     (ps) >= &_metal.page_sizes[0];				\
128 	     (ps)--)
129 
130 #endif
131 
132 #ifdef __cplusplus
133 }
134 #endif
135 
136 #endif /* __METAL_LINUX_SYS__H__ */
137