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

Last change on this file since 190 was 188, checked in by alain, 5 years ago

Redefine the PIC device API.

File size: 10.9 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_root_inode_xp,
56                     xptr_t        devfs_external_inode_xp )
57{
58    devfs_ctx->root_inode_xp     = devfs_root_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_root_inode_xp,
77                        xptr_t * devfs_external_inode_xp )
78{
79    error_t  error;
80
81    // creates DEVFS "dev" inode in cluster IO
82    error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
83                                     INODE_TYPE_DIR,
84                                     FS_TYPE_DEVFS,
85                                     parent_inode_xp,
86                                     "dev",
87                                     NULL,
88                                     devfs_root_inode_xp ); 
89
90    nolock_assert( (error == 0) , __FUNCTION__ , "cannot create <dev>\n" );
91
92    // create DEVFS "external" inode in cluster IO
93    error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
94                                     INODE_TYPE_DIR,
95                                     FS_TYPE_DEVFS,
96                                     *devfs_root_inode_xp,
97                                     "dev",
98                                     NULL,
99                                     devfs_external_inode_xp ); 
100
101    nolock_assert( (error == 0) , __FUNCTION__ , "cannot create <external>\n" );
102} 
103
104//////////////////////////////////////////////////
105void devfs_local_init( xptr_t devfs_root_inode_xp,
106                       xptr_t devfs_external_inode_xp )
107{
108    char          node_name[16];
109    xptr_t        chdev_xp;
110    cxy_t         chdev_cxy;
111    xptr_t        inode_xp;
112    xptr_t        internal_inode_xp;
113    uint32_t      channel;
114
115    // create "internal" directory linked to "dev"
116    snprintf( node_name , 16 , "internal_%x" , local_cxy );
117    vfs_add_child_in_parent( local_cxy,
118                             INODE_TYPE_DIR,
119                             FS_TYPE_DEVFS,
120                             devfs_root_inode_xp,
121                             node_name,
122                             NULL,
123                             &internal_inode_xp );
124
125    // create ICU chdev inode
126    chdev_xp = chdev_dir.icu[local_cxy];
127    if( chdev_xp != XPTR_NULL) 
128    {
129        vfs_add_child_in_parent( local_cxy,
130                                 INODE_TYPE_DEV,
131                                 FS_TYPE_DEVFS,
132                                 internal_inode_xp,
133                                 "icu",
134                                 GET_PTR( chdev_xp ),
135                                 &inode_xp );
136    }
137
138    // create MMC chdev inode
139    chdev_xp = chdev_dir.mmc[local_cxy];
140    if( chdev_xp != XPTR_NULL)
141    {
142        vfs_add_child_in_parent( local_cxy,
143                                 INODE_TYPE_DEV,
144                                 FS_TYPE_DEVFS,
145                                 internal_inode_xp,
146                                 "mmc",
147                                 GET_PTR( chdev_xp ),
148                                 &inode_xp );
149    }
150
151    // create DMA chdev inodes (one DMA channel per core)
152    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
153    {
154        chdev_xp = chdev_dir.dma[channel];
155        if( chdev_xp != XPTR_NULL)
156        {
157            snprintf( node_name , 16 , "dma_%d" , channel );
158            vfs_add_child_in_parent( local_cxy,
159                                     INODE_TYPE_DEV,
160                                     FS_TYPE_DEVFS,
161                                     internal_inode_xp,
162                                     node_name,
163                                     GET_PTR( chdev_xp ),
164                                     &inode_xp );
165        }
166    }
167
168    // create an IOB inode in cluster containing IOB chdev
169    chdev_xp = chdev_dir.iob;
170    if( chdev_xp != XPTR_NULL )
171    {
172        chdev_cxy = GET_CXY( chdev_xp );
173        if( chdev_cxy == local_cxy )
174        {
175            vfs_add_child_in_parent( local_cxy,
176                                     INODE_TYPE_DEV,
177                                     FS_TYPE_DEVFS,
178                                     devfs_external_inode_xp,
179                                     "iob",
180                                     GET_PTR( chdev_xp ),
181                                     &inode_xp );
182        }
183    }
184       
185    // create a PIC inode in cluster containing PIC chdev
186    chdev_xp = chdev_dir.pic;
187    if( chdev_xp != XPTR_NULL )
188    {
189        chdev_cxy = GET_CXY( chdev_xp );
190        if( chdev_cxy == local_cxy )
191        {
192            vfs_add_child_in_parent( local_cxy,
193                                     INODE_TYPE_DEV,
194                                     FS_TYPE_DEVFS,
195                                     devfs_external_inode_xp,
196                                     "pic",
197                                     GET_PTR( chdev_xp ),
198                                     &inode_xp );
199        }
200    }
201
202    // create a TXT inode in each cluster containing a TXT chdev
203    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
204    {
205        chdev_xp = chdev_dir.txt[channel];
206        if( chdev_xp != XPTR_NULL )
207        {
208            chdev_cxy = GET_CXY( chdev_xp );
209            if( chdev_cxy == local_cxy )
210            {
211                snprintf( node_name , 16 , "txt_%d" , channel );
212                vfs_add_child_in_parent( local_cxy,
213                                         INODE_TYPE_DEV,
214                                         FS_TYPE_DEVFS,
215                                         devfs_external_inode_xp,
216                                         node_name,
217                                         GET_PTR( chdev_xp ),
218                                         &inode_xp );
219            }
220        }
221    }
222
223    // create an IOC inode in each cluster containing an IOC chdev
224    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
225    {
226        chdev_xp = chdev_dir.ioc[channel];
227        if( chdev_xp != XPTR_NULL )
228        {
229            chdev_cxy = GET_CXY( chdev_xp );
230            if( chdev_cxy == local_cxy )
231            {
232                snprintf( node_name , 16 , "ioc_%d" , channel );
233                vfs_add_child_in_parent( local_cxy,
234                                         INODE_TYPE_DEV,
235                                         FS_TYPE_DEVFS,
236                                         devfs_external_inode_xp,
237                                         node_name,
238                                         GET_PTR( chdev_xp ),
239                                         &inode_xp );
240            }
241        }
242    }
243
244    // create a FBF inode in each cluster containing a FBF chdev
245    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
246    {
247        chdev_xp = chdev_dir.fbf[channel];
248        if( chdev_xp != XPTR_NULL )
249        {
250            chdev_cxy = GET_CXY( chdev_xp );
251            if( chdev_cxy == local_cxy )
252            {
253                snprintf( node_name , 16 , "fbf_%d" , channel );
254                vfs_add_child_in_parent( local_cxy,
255                                         INODE_TYPE_DEV,
256                                         FS_TYPE_DEVFS,
257                                         devfs_external_inode_xp,
258                                         node_name,
259                                         GET_PTR( chdev_xp ),
260                                         &inode_xp );
261            }
262        }
263    }
264
265    // create a NIC_RX inode in each cluster containing a NIC_RX chdev
266    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
267    {
268        chdev_xp = chdev_dir.nic_rx[channel];
269        if( chdev_xp != XPTR_NULL )
270        {
271            chdev_cxy = GET_CXY( chdev_xp );
272            if( chdev_cxy == local_cxy )
273            {
274                snprintf( node_name , 16 , "nic_rx_%d" , channel );
275                vfs_add_child_in_parent( local_cxy,
276                                         INODE_TYPE_DEV,
277                                         FS_TYPE_DEVFS,
278                                         devfs_external_inode_xp,
279                                         node_name,
280                                         GET_PTR( chdev_xp ),
281                                         &inode_xp );
282            }
283        }
284    }
285
286    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
287    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
288    {
289        chdev_xp = chdev_dir.nic_tx[channel];
290        if( chdev_xp != XPTR_NULL )
291        {
292            chdev_cxy = GET_CXY( chdev_xp );
293            if( chdev_cxy == local_cxy )
294            {
295                snprintf( node_name , 16 , "nic_tx_%d" , channel );
296                vfs_add_child_in_parent( local_cxy,
297                                         INODE_TYPE_DEV,
298                                         FS_TYPE_DEVFS,
299                                         devfs_external_inode_xp,
300                                         node_name,
301                                         GET_PTR( chdev_xp ),
302                                         &inode_xp );
303            }
304        }
305    }
306}  // end devfs_local_init()
307
Note: See TracBrowser for help on using the repository browser.