source: trunk/kernel/vfs/devfs.c@ 286

Last change on this file since 286 was 279, checked in by alain, 9 years ago

1) Introduce independant command fields for the various devices in the thread descriptor.
2) Introduce a new dev_pic_enable_ipi() function in the generic PIC device
3) Fix two bugs identified by Maxime in the scheduler initialisation, and in the sched_select().
4) fix several bugs in the TSAR hal_kentry.S.
5) Introduce a third kgiet segment (besides kdata and kcode) in the TSAR bootloader.

File size: 10.8 KB
Line 
1/*
2 * devfs.c - DEVFS File system API implementation.
3 *
4 * Author Mohamed Lamine Karaoui (2014,2015)
5 * Alain Greiner (2016,2017)
6 *
7 * Copyright (c) Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#include <hal_types.h>
26#include <hal_special.h>
27#include <printk.h>
28#include <chdev.h>
29#include <cluster.h>
30#include <vfs.h>
31#include <kmem.h>
32#include <devfs.h>
33
34/////////////////////////////////////////////////////////////////////////////////////////
35// Extern variables
36/////////////////////////////////////////////////////////////////////////////////////////
37
38extern vfs_ctx_t fs_context[]; // allocated in kernel_init.c
39extern chdev_directory_t chdev_dir; // allocated in kernel_init.c
40
41///////////////////////////////
42devfs_ctx_t * devfs_ctx_alloc()
43{
44 kmem_req_t req;
45
46 req.type = KMEM_DEVFS_CTX;
47 req.size = sizeof(devfs_ctx_t);
48 req.flags = AF_KERNEL | AF_ZERO;
49
50 return (devfs_ctx_t *)kmem_alloc( &req );
51}
52
53/////////////////////////////////////////////
54void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
55 xptr_t devfs_dev_inode_xp,
56 xptr_t devfs_external_inode_xp )
57{
58 devfs_ctx->dev_inode_xp = devfs_dev_inode_xp;
59 devfs_ctx->external_inode_xp = devfs_external_inode_xp;
60
61 fs_context[FS_TYPE_DEVFS].extend = devfs_ctx;
62}
63
64/////////////////////////////////////////////////
65void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx )
66{
67 kmem_req_t req;
68
69 req.type = KMEM_DEVFS_CTX;
70 req.ptr = devfs_ctx;
71 kmem_free( &req );
72}
73
74///////////////////////////////////////////////////
75void devfs_global_init( xptr_t parent_inode_xp,
76 xptr_t * devfs_dev_inode_xp,
77 xptr_t * devfs_external_inode_xp )
78{
79 error_t error;
80
81 devfs_dmsg("\n[INFO] %s : enter in cluster %x\n",
82 __FUNCTION__ , local_cxy );
83
84 // creates DEVFS "dev" inode in cluster IO
85 error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
86 INODE_TYPE_DIR,
87 FS_TYPE_DEVFS,
88 parent_inode_xp,
89 "dev",
90 NULL,
91 devfs_dev_inode_xp );
92
93 assert( (error == 0) , __FUNCTION__ , "cannot create <dev>\n" );
94
95 devfs_dmsg("\n[INFO] %s : <dev> created in cluster %x\n",
96 __FUNCTION__ , local_cxy );
97
98 // create DEVFS "external" inode in cluster IO
99 error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
100 INODE_TYPE_DIR,
101 FS_TYPE_DEVFS,
102 *devfs_dev_inode_xp,
103 "external",
104 NULL,
105 devfs_external_inode_xp );
106
107 assert( (error == 0) , __FUNCTION__ , "cannot create <external>\n" );
108
109 devfs_dmsg("\n[INFO] %s : <external> created in cluster %x\n",
110 __FUNCTION__ , local_cxy );
111}
112
113///////////////////////////////////////////////////
114void devfs_local_init( xptr_t devfs_dev_inode_xp,
115 xptr_t devfs_external_inode_xp,
116 xptr_t * devfs_internal_inode_xp )
117{
118 char node_name[16];
119 xptr_t chdev_xp;
120 cxy_t chdev_cxy;
121 xptr_t inode_xp;
122 uint32_t channel;
123
124 // create "internal" directory linked to "dev"
125 snprintf( node_name , 16 , "internal_%x" , local_cxy );
126 vfs_add_child_in_parent( local_cxy,
127 INODE_TYPE_DIR,
128 FS_TYPE_DEVFS,
129 devfs_dev_inode_xp,
130 node_name,
131 NULL,
132 devfs_internal_inode_xp );
133
134 // create MMC chdev inode
135 chdev_xp = chdev_dir.mmc[local_cxy];
136 if( chdev_xp != XPTR_NULL)
137 {
138 vfs_add_child_in_parent( local_cxy,
139 INODE_TYPE_DEV,
140 FS_TYPE_DEVFS,
141 *devfs_internal_inode_xp,
142 "mmc",
143 GET_PTR( chdev_xp ),
144 &inode_xp );
145 }
146
147 // create DMA chdev inodes (one DMA channel per core)
148 for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
149 {
150 chdev_xp = chdev_dir.dma[channel];
151 if( chdev_xp != XPTR_NULL)
152 {
153 snprintf( node_name , 16 , "dma_%d" , channel );
154 vfs_add_child_in_parent( local_cxy,
155 INODE_TYPE_DEV,
156 FS_TYPE_DEVFS,
157 *devfs_internal_inode_xp,
158 node_name,
159 GET_PTR( chdev_xp ),
160 &inode_xp );
161 }
162 }
163
164 // create an IOB inode in cluster containing IOB chdev
165 chdev_xp = chdev_dir.iob;
166 if( chdev_xp != XPTR_NULL )
167 {
168 chdev_cxy = GET_CXY( chdev_xp );
169 if( chdev_cxy == local_cxy )
170 {
171 vfs_add_child_in_parent( local_cxy,
172 INODE_TYPE_DEV,
173 FS_TYPE_DEVFS,
174 devfs_external_inode_xp,
175 "iob",
176 GET_PTR( chdev_xp ),
177 &inode_xp );
178 }
179 }
180
181 // create a PIC inode in cluster containing PIC chdev
182 chdev_xp = chdev_dir.pic;
183 if( chdev_xp != XPTR_NULL )
184 {
185 chdev_cxy = GET_CXY( chdev_xp );
186 if( chdev_cxy == local_cxy )
187 {
188 vfs_add_child_in_parent( local_cxy,
189 INODE_TYPE_DEV,
190 FS_TYPE_DEVFS,
191 devfs_external_inode_xp,
192 "pic",
193 GET_PTR( chdev_xp ),
194 &inode_xp );
195 }
196 }
197
198 // create a TXT inode in each cluster containing a TXT chdev
199 for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
200 {
201 chdev_xp = chdev_dir.txt[channel];
202 if( chdev_xp != XPTR_NULL )
203 {
204 chdev_cxy = GET_CXY( chdev_xp );
205 if( chdev_cxy == local_cxy )
206 {
207 snprintf( node_name , 16 , "txt_%d" , channel );
208 vfs_add_child_in_parent( local_cxy,
209 INODE_TYPE_DEV,
210 FS_TYPE_DEVFS,
211 devfs_external_inode_xp,
212 node_name,
213 GET_PTR( chdev_xp ),
214 &inode_xp );
215 }
216 }
217 }
218
219 // create an IOC inode in each cluster containing an IOC chdev
220 for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
221 {
222 chdev_xp = chdev_dir.ioc[channel];
223 if( chdev_xp != XPTR_NULL )
224 {
225 chdev_cxy = GET_CXY( chdev_xp );
226 if( chdev_cxy == local_cxy )
227 {
228 snprintf( node_name , 16 , "ioc_%d" , channel );
229 vfs_add_child_in_parent( local_cxy,
230 INODE_TYPE_DEV,
231 FS_TYPE_DEVFS,
232 devfs_external_inode_xp,
233 node_name,
234 GET_PTR( chdev_xp ),
235 &inode_xp );
236 }
237 }
238 }
239
240 // create a FBF inode in each cluster containing a FBF chdev
241 for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
242 {
243 chdev_xp = chdev_dir.fbf[channel];
244 if( chdev_xp != XPTR_NULL )
245 {
246 chdev_cxy = GET_CXY( chdev_xp );
247 if( chdev_cxy == local_cxy )
248 {
249 snprintf( node_name , 16 , "fbf_%d" , channel );
250 vfs_add_child_in_parent( local_cxy,
251 INODE_TYPE_DEV,
252 FS_TYPE_DEVFS,
253 devfs_external_inode_xp,
254 node_name,
255 GET_PTR( chdev_xp ),
256 &inode_xp );
257 }
258 }
259 }
260
261 // create a NIC_RX inode in each cluster containing a NIC_RX chdev
262 for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
263 {
264 chdev_xp = chdev_dir.nic_rx[channel];
265 if( chdev_xp != XPTR_NULL )
266 {
267 chdev_cxy = GET_CXY( chdev_xp );
268 if( chdev_cxy == local_cxy )
269 {
270 snprintf( node_name , 16 , "nic_rx_%d" , channel );
271 vfs_add_child_in_parent( local_cxy,
272 INODE_TYPE_DEV,
273 FS_TYPE_DEVFS,
274 devfs_external_inode_xp,
275 node_name,
276 GET_PTR( chdev_xp ),
277 &inode_xp );
278 }
279 }
280 }
281
282 // create a NIC_TX inode in each cluster containing a NIC_TX chdev
283 for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
284 {
285 chdev_xp = chdev_dir.nic_tx[channel];
286 if( chdev_xp != XPTR_NULL )
287 {
288 chdev_cxy = GET_CXY( chdev_xp );
289 if( chdev_cxy == local_cxy )
290 {
291 snprintf( node_name , 16 , "nic_tx_%d" , channel );
292 vfs_add_child_in_parent( local_cxy,
293 INODE_TYPE_DEV,
294 FS_TYPE_DEVFS,
295 devfs_external_inode_xp,
296 node_name,
297 GET_PTR( chdev_xp ),
298 &inode_xp );
299 }
300 }
301 }
302} // end devfs_local_init()
303
Note: See TracBrowser for help on using the repository browser.