source: trunk/kernel/syscalls/sys_fbf.c @ 646

Last change on this file since 646 was 642, checked in by alain, 5 years ago

Introduce two new syscalls : sys_get_thread_info() / sys_fbf()

File size: 5.6 KB
Line 
1/*
2 * sys_fbf.c - Acces the frame buffer peripheral.
3 *
4 * Authors     Alain Greiner (2016,2017,2018,2019)
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 <hal_kernel_types.h>
25#include <hal_uspace.h>
26#include <hal_vmm.h>
27#include <shared_fbf.h>
28#include <dev_fbf.h>
29#include <errno.h>
30#include <thread.h>
31#include <printk.h>
32#include <vmm.h>
33#include <syscalls.h>
34
35//////////////////////////////////
36int sys_fbf( uint32_t   operation,
37             void     * arg0,           
38             void     * arg1,
39             void     * arg2 )
40{
41        vseg_t         * vseg;        // for vaddr check
42    error_t          error;
43
44    thread_t       * this    = CURRENT_THREAD;
45    process_t      * process = this->process;
46
47#if (DEBUG_SYS_FBF || CONFIG_INSTRUMENTATION_SYSCALLS)
48uint64_t     tm_start = hal_get_cycles();
49#endif
50
51#if DEBUG_SYS_FBF
52if( DEBUG_SYS_FBF < tm_start )
53printk("\n[%s] thread[%x,%x] enter for %s / cycle %d\n",
54__FUNCTION__, process->pid, this->trdid, dev_fbf_cmd_str( operation ), (uint32_t)tm_start );
55#endif
56
57    // execute requested operation
58        switch( operation )
59        {
60        ////////////////////
61            case FBF_GET_CONFIG:
62        {
63            uint32_t width;
64            uint32_t height;
65            uint32_t type;
66
67            // check arg0 (width) in user vspace
68                error = vmm_get_vseg( process , (intptr_t)arg0 , &vseg );
69                if( error )
70            {
71
72#if DEBUG_SYSCALLS_ERROR
73printk("\n[ERROR] in %s : unmapped arg0 %x for %s / thread[%x,%x]\n",
74__FUNCTION__ , arg0, dev_fbf_cmd_str(operation), process->pid, this->trdid );
75#endif
76                this->errno = EINVAL;
77                return -1;
78            }
79
80            // check arg1 (height) in user vspace
81                error = vmm_get_vseg( process , (intptr_t)arg1 , &vseg );
82                if( error )
83            {
84
85#if DEBUG_SYSCALLS_ERROR
86printk("\n[ERROR] in %s : unmapped arg1 %x for %s / thread[%x,%x]\n",
87__FUNCTION__ , arg1, dev_fbf_cmd_str(operation), process->pid, this->trdid );
88#endif
89                this->errno = EINVAL;
90                return -1;
91            }
92
93            // check arg2 (type) in user vspace
94                error = vmm_get_vseg( process , (intptr_t)arg2 , &vseg );
95                if( error )
96            {
97
98#if DEBUG_SYSCALLS_ERROR
99printk("\n[ERROR] in %s : unmapped arg2 %x for %s / thread[%x,%x]\n",
100__FUNCTION__ , arg2, dev_fbf_cmd_str(operation), process->pid, this->trdid );
101#endif
102                this->errno = EINVAL;
103                return -1;
104            }
105
106            // call relevant kernel function to get  config
107            dev_fbf_get_config( &width , &height , &type );
108
109            // transfer to user space
110            hal_copy_to_uspace( arg0 , XPTR( local_cxy , &width )  , sizeof(uint32_t) );
111            hal_copy_to_uspace( arg1 , XPTR( local_cxy , &height ) , sizeof(uint32_t) );
112            hal_copy_to_uspace( arg2 , XPTR( local_cxy , &type )   , sizeof(uint32_t) );
113       
114            break;
115        }
116        //////////////
117        case FBF_READ:
118        case FBF_WRITE:
119        {
120            // check arg0 (buffer) in user space
121                error = vmm_get_vseg( process , (intptr_t)arg0 , &vseg );
122                if( error )
123            {
124
125#if DEBUG_SYSCALLS_ERROR
126printk("\n[ERROR] in %s : unmapped arg0 %x for %s / thread[%x,%x]\n",
127__FUNCTION__ , arg0, dev_fbf_cmd_str(operation), process->pid, this->trdid );
128#endif
129                this->errno = EINVAL;
130                return -1;
131            }
132
133            // get length and offset values
134
135            uint32_t length = (uint32_t)(intptr_t)arg1;
136            uint32_t offset = (uint32_t)(intptr_t)arg2;
137
138            // call relevant kernel function to move data
139            error = dev_fbf_move_data( operation , arg0 , length , offset ); 
140
141            if( error )
142            {
143
144#if DEBUG_SYSCALLS_ERROR
145printk("\n[ERROR] in %s : cannot move data for %s / buffer %x / thread[%x,%x]\n",
146__FUNCTION__ , dev_fbf_cmd_str(operation), arg0, process->pid, this->trdid );
147#endif
148                this->errno = EINVAL;
149                return -1;
150            }
151         
152            break;
153        }
154        ///////
155            default:  // undefined operation                       
156        {
157
158#if DEBUG_SYSCALLS_ERROR
159printk("\n[ERROR] in %s : undefined operation type %d / thread %x in process %x / cycle %d\n",
160__FUNCTION__ , operation, this->trdid, process->pid, (uint32_t)hal_get_cycles() );
161#endif
162            this->errno = EINVAL;
163            return -1;
164        }
165        }  // end switch on operation
166
167    hal_fence();
168
169#if (DEBUG_SYS_FBF || CONFIG_INSTRUMENTATION_SYSCALLS)
170uint64_t     tm_end = hal_get_cycles();
171#endif
172
173#if DEBUG_SYS_FBF
174if( DEBUG_SYS_FBF < tm_end )
175printk("\n[DBG] %s : thread %x in process %x exit for %s / cost = %d / cycle %d\n",
176__FUNCTION__, this->trdid, process->pid, dev_fbf_cmd_str( operation ),
177(uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
178#endif
179
180#if CONFIG_INSTRUMENTATION_SYSCALLS
181hal_atomic_add( &syscalls_cumul_cost[SYS_FBF] , tm_end - tm_start );
182hal_atomic_add( &syscalls_occurences[SYS_FBF] , 1 );
183#endif
184
185    return 0;
186
187}  // end sys_fbf()
Note: See TracBrowser for help on using the repository browser.