source: trunk/kernel/kern/device.c @ 4

Last change on this file since 4 was 1, checked in by alain, 8 years ago

First import

File size: 5.1 KB
Line 
1/*
2 * device.c - device descriptor operations implementation
3 *
4 * Authors  Alain Greiner   (2016)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH.is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH.is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH.; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <almos_config.h>
25#include <hal_types.h>
26#include <hal_special.h>
27#include <boot_info.h>
28#include <xlist.h>
29#include <kmem.h>
30#include <thread.h>
31#include <rpc.h>
32#include <device.h>
33
34////////////////////////////////////////////////////////////////////////////////////
35// This array defines printable strings for devices functionnal types.
36////////////////////////////////////////////////////////////////////////////////////
37
38char * device_func_str[DEV_FUNC_NR] = 
39{
40        "RAM",
41        "ROM",
42        "TXT",
43    "FBF",
44    "IOB",
45    "IOC",
46    "MMC",
47    "MWR",
48    "NIC",
49    "CMA",
50    "XCU",
51    "PIC"
52};
53
54////////////////////////////////////////
55xptr_t device_alloc( boot_info_t * info,
56                     bool_t        is_local )
57{
58    xptr_t     dev_xp;
59    device_t * dev_ptr;
60    uint32_t   index;
61    uint32_t   x;
62    uint32_t   y;
63    cxy_t      target_cxy;
64    kmem_req_t req;
65    error_t    error;
66
67    if( is_local )  // forced local allocation
68    {
69        req.type   = KMEM_DEVICE;
70        req.flags  = AF_ZERO;
71        dev_ptr    = (device_t *)kmem_alloc( &req );
72
73        if( dev_ptr == NULL ) return XPTR_NULL;
74        else                  return ( XPTR( local_cxy , dev_ptr ) );
75    }
76    else            // likely remote allocation
77    {
78        // select (pseudo-randomly) a target cluster
79        index      = ( hal_time_stamp() + hal_get_gid() ) % (info->x_size * info->y_size);
80        x          = index / info->y_size;   
81        y          = index % info->y_size;
82        target_cxy = (x<<info->y_width) + y;
83
84        if( target_cxy == local_cxy )   // local allocation
85        {
86            req.type   = KMEM_DEVICE;
87            req.flags  = AF_ZERO;
88            dev_ptr    = (device_t *)kmem_alloc( &req );
89
90            if( dev_ptr == NULL ) return XPTR_NULL;
91            else                  return ( XPTR( local_cxy , dev_ptr ) );
92        }
93        else                          // remote allocation
94        {
95            rpc_device_alloc_client( target_cxy , &dev_xp , &error );
96            if( error ) return XPTR_NULL;
97            else        return ( dev_xp );
98             
99        }
100    }   
101} // end device_alloc()
102
103
104/////////////////////////////////////
105void device_init( xptr_t      device,
106                  uint32_t    func,
107                  uint32_t    impl,
108                  uint32_t    channel,
109                  uint32_t    is_rx,
110                  xptr_t      base,
111                  uint32_t    size )
112{
113    // get device cluster and local pointer
114    cxy_t      cxy = GET_CXY( device );
115    device_t * ptr = (device_t *)GET_PTR( device );
116
117    // initialize waiting threads queue and associated lock
118    remote_spinlock_init( XPTR( cxy , &ptr->wait_lock ) );
119    xlist_root_init( XPTR( cxy , &ptr->wait_root ) );
120
121    // initialize basic attributes
122    hal_remote_sw ( XPTR( cxy , &ptr->func    ) , (uint32_t)func    );
123    hal_remote_sw ( XPTR( cxy , &ptr->impl    ) , (uint32_t)impl    );
124    hal_remote_sw ( XPTR( cxy , &ptr->channel ) , (uint32_t)channel );
125    hal_remote_sw ( XPTR( cxy , &ptr->is_rx   ) , (uint32_t)is_rx   );
126    hal_remote_swd( XPTR( cxy , &ptr->base    ) , (uint64_t)base    ); 
127    hal_remote_sw ( XPTR( cxy , &ptr->size    ) , (uint64_t)size    ); 
128
129}  // end device_init()
130
131////////////////////////////////////////////////
132void device_register_command( xptr_t     xp_dev,
133                              thread_t * thread )
134{
135    thread_t * thread_ptr = CURRENT_THREAD;
136
137    // get device descriptor cluster and local pointer
138    cxy_t      dev_cxy = GET_CXY( xp_dev );
139    device_t * dev_ptr = (device_t *)GET_PTR( xp_dev );
140
141    // build extended pointers on client thread xlist and device root
142    xptr_t  xp_list = XPTR( local_cxy , &thread_ptr->wait_list );
143    xptr_t  xp_root = XPTR( dev_cxy , &dev_ptr->wait_root );
144
145    // get lock protecting queue
146    remote_spinlock_lock( XPTR( dev_cxy , &dev_ptr->wait_lock ) );
147
148    // register client thread in waiting queue
149    xlist_add_last( xp_root , xp_list );
150
151    // unblock server thread
152    thread_unblock( XPTR( dev_cxy , &dev_ptr->server ) , THREAD_BLOCKED_DEV_QUEUE );
153
154    // release lock
155    remote_spinlock_unlock( XPTR( dev_cxy , &dev_ptr->wait_lock ) );
156
157    // client thread goes to blocked state and deschedule
158    thread_block( thread_ptr , THREAD_BLOCKED_IO );
159    sched_yield();
160
161}  // end device register_command()
162
Note: See TracBrowser for help on using the repository browser.