Subversion Repositories HelenOS

Rev

Rev 2927 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2927 Rev 3150
Line 49... Line 49...
49
#include <errno.h>
49
#include <errno.h>
50
#include <async.h>
50
#include <async.h>
51
#include <align.h>
51
#include <align.h>
52
#include <async.h>
52
#include <async.h>
53
#include <futex.h>
53
#include <futex.h>
-
 
54
#include <stdio.h>
-
 
55
#include <ipc/devmap.h>
54
#include "rd.h"
56
#include "rd.h"
55
 
57
 
-
 
58
#define NAME "rd"
-
 
59
 
56
/** Pointer to the ramdisk's image. */
60
/** Pointer to the ramdisk's image. */
57
static void *rd_addr;
61
static void *rd_addr;
58
/** Size of the ramdisk. */
62
/** Size of the ramdisk. */
59
static size_t rd_size;
63
static size_t rd_size;
60
 
64
 
Line 102... Line 106...
102
 
106
 
103
    /*
107
    /*
104
     * Now we wait for the client to send us its communication as_area.
108
     * Now we wait for the client to send us its communication as_area.
105
     */
109
     */
106
    size_t size;
110
    size_t size;
-
 
111
    int flags;
107
    if (ipc_share_out_receive(&callid, &size, NULL)) {
112
    if (ipc_share_out_receive(&callid, &size, &flags)) {
108
        if (size >= BLOCK_SIZE) {
113
        if (size >= BLOCK_SIZE) {
109
            /*
114
            /*
110
             * The client sends an as_area that can absorb the whole
115
             * The client sends an as_area that can absorb the whole
111
             * block.
116
             * block.
112
             */
117
             */
Line 147... Line 152...
147
                 */
152
                 */
148
                retval = ELIMIT;
153
                retval = ELIMIT;
149
                break;
154
                break;
150
            }
155
            }
151
            futex_down(&rd_futex);
156
            futex_down(&rd_futex);
152
            memcpy(fs_va, rd_addr + offset, BLOCK_SIZE);
157
            memcpy(fs_va, rd_addr + offset * BLOCK_SIZE, BLOCK_SIZE);
153
            futex_up(&rd_futex);
158
            futex_up(&rd_futex);
154
            retval = EOK;
159
            retval = EOK;
155
            break;
160
            break;
156
        case RD_WRITE_BLOCK:
161
        case RD_WRITE_BLOCK:
157
            offset = IPC_GET_ARG1(call);
162
            offset = IPC_GET_ARG1(call);
Line 161... Line 166...
161
                 */
166
                 */
162
                retval = ELIMIT;
167
                retval = ELIMIT;
163
                break;
168
                break;
164
            }
169
            }
165
            futex_up(&rd_futex);
170
            futex_up(&rd_futex);
166
            memcpy(rd_addr + offset, fs_va, BLOCK_SIZE);
171
            memcpy(rd_addr + offset * BLOCK_SIZE, fs_va, BLOCK_SIZE);
167
            futex_down(&rd_futex);
172
            futex_down(&rd_futex);
168
            retval = EOK;
173
            retval = EOK;
169
            break;
174
            break;
170
        default:
175
        default:
171
            /*
176
            /*
Line 179... Line 184...
179
        }
184
        }
180
        ipc_answer_0(callid, retval);
185
        ipc_answer_0(callid, retval);
181
    }
186
    }
182
}
187
}
183
 
188
 
-
 
189
static int driver_register(char *name)
-
 
190
{
-
 
191
    ipcarg_t retval;
-
 
192
    aid_t req;
-
 
193
    ipc_call_t answer;
-
 
194
    int phone;
-
 
195
    ipcarg_t callback_phonehash;
-
 
196
 
-
 
197
    phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
-
 
198
 
-
 
199
    while (phone < 0) {
-
 
200
        usleep(10000);
-
 
201
        phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
-
 
202
            DEVMAP_DRIVER, 0);
-
 
203
    }
-
 
204
   
-
 
205
    req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
-
 
206
 
-
 
207
    retval = ipc_data_write_start(phone, (char *) name, strlen(name) + 1);
-
 
208
 
-
 
209
    if (retval != EOK) {
-
 
210
        async_wait_for(req, NULL);
-
 
211
        return -1;
-
 
212
    }
-
 
213
 
-
 
214
    async_set_client_connection(rd_connection);
-
 
215
 
-
 
216
    ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
-
 
217
    async_wait_for(req, &retval);
-
 
218
 
-
 
219
    return phone;
-
 
220
}
-
 
221
 
-
 
222
static int device_register(int driver_phone, char *name, int *handle)
-
 
223
{
-
 
224
    ipcarg_t retval;
-
 
225
    aid_t req;
-
 
226
    ipc_call_t answer;
-
 
227
 
-
 
228
    req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
-
 
229
 
-
 
230
    retval = ipc_data_write_start(driver_phone, (char *) name, strlen(name) + 1);
-
 
231
 
-
 
232
    if (retval != EOK) {
-
 
233
        async_wait_for(req, NULL);
-
 
234
        return retval;
-
 
235
    }
-
 
236
 
-
 
237
    async_wait_for(req, &retval);
-
 
238
 
-
 
239
    if (handle != NULL)
-
 
240
        *handle = -1;
-
 
241
   
-
 
242
    if (EOK == retval) {
-
 
243
        if (NULL != handle)
-
 
244
            *handle = (int) IPC_GET_ARG1(answer);
-
 
245
    }
-
 
246
   
-
 
247
    return retval;
-
 
248
}
-
 
249
 
184
/** Prepare the ramdisk image for operation. */
250
/** Prepare the ramdisk image for operation. */
185
static bool rd_init(void)
251
static bool rd_init(void)
186
{
252
{
187
    int retval, flags;
-
 
188
 
-
 
189
    rd_size = sysinfo_value("rd.size");
253
    rd_size = sysinfo_value("rd.size");
190
    void *rd_ph_addr = (void *) sysinfo_value("rd.address.physical");
254
    void *rd_ph_addr = (void *) sysinfo_value("rd.address.physical");
191
   
255
   
192
    if (rd_size == 0)
256
    if (rd_size == 0) {
-
 
257
        printf(NAME ": No RAM disk found\n");
193
        return false;
258
        return false;
-
 
259
    }
194
   
260
   
195
    rd_addr = as_get_mappable_page(rd_size);
261
    rd_addr = as_get_mappable_page(rd_size);
196
   
262
   
197
    flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
263
    int flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE;
198
    retval = physmem_map(rd_ph_addr, rd_addr,
264
    int retval = physmem_map(rd_ph_addr, rd_addr,
199
        ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
265
        ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
200
 
266
 
201
    if (retval < 0)
267
    if (retval < 0) {
-
 
268
        printf(NAME ": Error mapping RAM disk\n");
-
 
269
        return false;
-
 
270
    }
-
 
271
   
-
 
272
    printf(NAME ": Found RAM disk at %p, %d bytes\n", rd_ph_addr, rd_size);
-
 
273
   
-
 
274
    int driver_phone = driver_register(NAME);
-
 
275
    if (driver_phone < 0) {
-
 
276
        printf(NAME ": Unable to register driver\n");
-
 
277
        return false;
-
 
278
    }
-
 
279
   
-
 
280
    int dev_handle;
-
 
281
    if (EOK != device_register(driver_phone, "initrd", &dev_handle)) {
-
 
282
        ipc_hangup(driver_phone);
-
 
283
        printf(NAME ": Unable to register device\n");
202
        return false;
284
        return false;
-
 
285
    }
-
 
286
   
203
    return true;
287
    return true;
204
}
288
}
205
 
289
 
206
int main(int argc, char **argv)
290
int main(int argc, char **argv)
207
{
291
{
208
    if (rd_init()) {
-
 
209
        ipcarg_t phonead;
-
 
210
       
-
 
211
        async_set_client_connection(rd_connection);
-
 
212
       
-
 
213
        /* Register service at nameserver */
292
    printf(NAME ": HelenOS RAM disk server\n");
214
        if (ipc_connect_to_me(PHONE_NS, SERVICE_RD, 0, 0, &phonead) != 0)
-
 
215
            return -1;
-
 
216
       
-
 
217
        async_manager();
-
 
218
       
-
 
219
        /* Never reached */
-
 
220
        return 0;
-
 
221
    }
-
 
222
   
293
   
-
 
294
    if (!rd_init())
223
    return -1;
295
        return -1;
-
 
296
   
-
 
297
    printf(NAME ": Accepting connections\n");
-
 
298
    async_manager();
-
 
299
 
-
 
300
    /* Never reached */
-
 
301
    return 0;
224
}
302
}
225
 
303
 
226
/**
304
/**
227
 * @}
305
 * @}
228
 */
306
 */