use the -newos toolchain even if -elf is present.
[newos.git] / kernel / dev / beos.c
blob07515bff67851f704cf00fb2d643776fbeb24054
1 /*
2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <kernel/kernel.h>
6 #include <kernel/elf.h>
7 #include <kernel/sem.h>
8 #include <kernel/time.h>
9 #include <kernel/arch/cpu.h>
10 #include <kernel/debug.h>
11 #include <kernel/heap.h>
12 #include <kernel/fs/devfs.h>
13 #include <kernel/dev/beos.h>
14 #include <string.h>
15 #include <stdio.h>
17 #ifdef ARCH_i386
19 // contains a bunch of beos defines
20 #include "beos_p.h"
22 // private funcs
23 static uint8 read8(int port);
24 static void write8(int port, uint8 data);
25 static uint16 read16(int port);
26 static void write16(int port, uint16 data);
27 static uint32 read32(int port);
28 static void write32(int port, uint32 data);
29 static void unhandled_isa_call(void);
31 static int translation_open(dev_ident ident, dev_cookie *cookie);
32 static int translation_close(dev_cookie cookie);
33 static int translation_freecookie(dev_cookie cookie);
34 static int translation_seek(dev_cookie cookie, off_t pos, seek_type st);
35 static int translation_ioctl(dev_cookie cookie, int op, void *buf, size_t len);
36 static ssize_t translation_read(dev_cookie cookie, void *buf, off_t pos, ssize_t len);
37 static ssize_t translation_write(dev_cookie cookie, const void *buf, off_t pos, ssize_t len);
38 static int translation_canpage(dev_ident ident);
39 static ssize_t translation_readpage(dev_ident ident, iovecs *vecs, off_t pos);
40 static ssize_t translation_writepage(dev_ident ident, iovecs *vecs, off_t pos);
42 static int newos2beos_err(int err);
43 static int beos2newos_err(int err);
45 /* device translation object */
46 struct beos_device_node {
47 struct beos_device_node *next;
48 const char *name;
50 beos_device_hooks *beos_hooks;
53 struct beos_device_node *nodes = NULL;
55 /* our cookie, which will wrap around the beos cookie */
56 struct beos_device_cookie {
57 struct beos_device_node *node;
58 void *beos_cookie;
59 off_t pos;
62 /* our device hooks structure */
63 struct dev_calls translation_hooks = {
64 &translation_open,
65 &translation_close,
66 &translation_freecookie,
67 &translation_seek,
68 &translation_ioctl,
69 &translation_read,
70 &translation_write,
71 &translation_canpage,
72 &translation_readpage,
73 &translation_writepage
76 isa_module_info isa = {
77 { /* binfo */
78 { "isa", 0, NULL }, /* minfo */
79 (void *)unhandled_isa_call
81 read8,
82 write8,
83 read16,
84 write16,
85 read32,
86 write32,
87 (void *)unhandled_isa_call,
88 (void *)unhandled_isa_call,
89 (void *)unhandled_isa_call,
90 (void *)unhandled_isa_call,
91 (void *)unhandled_isa_call,
92 (void *)unhandled_isa_call
95 struct module {
96 const char *name;
97 void *data;
98 } modules[] = {
99 { B_ISA_MODULE_NAME, &isa },
100 { NULL, NULL }
103 int beos_layer_init(void)
105 return 0;
108 int _beos_atomic_add(volatile int *val, int incr)
110 return atomic_add(val, incr);
113 int _beos_atomic_and(volatile int *val, int incr)
115 return atomic_and(val, incr);
118 int _beos_atomic_or(volatile int *val, int incr)
120 return atomic_or(val, incr);
123 int _beos_acquire_sem(sem_id id)
125 return newos2beos_err(sem_acquire(id, 1));
128 int _beos_acquire_sem_etc(sem_id id, uint32 count, uint32 flags, bigtime_t timeout)
130 int nuflags = 0;
131 bigtime_t nutimeout = timeout;
133 if(flags & B_CAN_INTERRUPT)
134 nuflags |= SEM_FLAG_INTERRUPTABLE;
135 if(flags & B_DO_NOT_RESCHEDULE)
136 nuflags |= SEM_FLAG_NO_RESCHED;
137 if(flags & B_RELATIVE_TIMEOUT)
138 nuflags |= SEM_FLAG_TIMEOUT;
139 if(flags & B_ABSOLUTE_TIMEOUT) {
140 nuflags |= SEM_FLAG_TIMEOUT;
141 nutimeout = timeout - system_time();
142 if(nutimeout < 0)
143 nutimeout = 0;
145 return newos2beos_err(sem_acquire_etc(id, count, nuflags, nutimeout, NULL));
148 sem_id _beos_create_sem(uint32 count, const char *name)
150 return newos2beos_err(sem_create(count, name));
153 int _beos_delete_sem(sem_id id)
155 return newos2beos_err(sem_delete(id));
158 int _beos_get_sem_count(sem_id id, int32 *count)
160 panic("_beos_get_sem_count: not supported\n");
161 return 0;
164 int _beos_release_sem(sem_id id)
166 return newos2beos_err(sem_release(id, 1));
169 int _beos_release_sem_etc(sem_id id, int32 count, uint32 flags)
171 int nuflags = 0;
173 if(flags & B_DO_NOT_RESCHEDULE)
174 nuflags = SEM_FLAG_NO_RESCHED;
176 return newos2beos_err(sem_release_etc(id, count, nuflags));
179 int _beos_strcmp(const char *cs, const char *ct)
181 return strcmp(cs, ct);
184 void _beos_spin(bigtime_t microseconds)
186 bigtime_t time = system_time();
188 while((system_time() - time) < microseconds)
192 int _beos_get_module(const char *path, module_info **vec)
194 struct module *m;
196 dprintf("get_module: called on '%s'\n", path);
197 for(m = modules; m->name; m++) {
198 if(!strcmp(path, m->name)) {
199 *vec = m->data;
200 return NO_ERROR;
203 return ERR_GENERAL;
206 int _beos_put_module(const char *path)
208 dprintf("put_module: called on '%s'\n", path);
209 return NO_ERROR;
212 static uint8 read8(int port)
214 return in8(port);
217 static void write8(int port, uint8 data)
219 // dprintf("w8 0x%x, 0x%x\n", port, data);
220 out8(data, port);
223 static uint16 read16(int port)
225 return in16(port);
228 static void write16(int port, uint16 data)
230 // dprintf("w16 0x%x, 0x%x\n", port, data);
231 out16(data, port);
234 static uint32 read32(int port)
236 return in32(port);
239 static void write32(int port, uint32 data)
241 // dprintf("w32 0x%x, 0x%x\n", port, data);
242 out32(data, port);
245 static void unhandled_isa_call(void)
247 panic("call into unhandled isa function\n");
250 static int beos2newos_err(int err)
252 if(err >= 0)
253 return err;
255 switch(err) {
256 case B_NO_MEMORY: return ERR_NO_MEMORY;
257 case B_IO_ERROR: return ERR_IO_ERROR;
258 case B_PERMISSION_DENIED: return ERR_PERMISSION_DENIED;
259 case B_NAME_NOT_FOUND: return ERR_NOT_FOUND;
260 case B_TIMED_OUT: return ERR_SEM_TIMED_OUT;
261 case B_INTERRUPTED: return ERR_INTERRUPTED;
262 case B_NOT_ALLOWED: return ERR_NOT_ALLOWED;
263 case B_ERROR: return ERR_GENERAL;
264 case B_BAD_SEM_ID: return ERR_INVALID_HANDLE;
265 case B_NO_MORE_SEMS: return ERR_SEM_OUT_OF_SLOTS;
266 case B_BAD_THREAD_ID: return ERR_INVALID_HANDLE;
267 case B_NO_MORE_THREADS: return ERR_NO_MORE_HANDLES;
268 case B_BAD_TEAM_ID: return ERR_INVALID_HANDLE;
269 case B_NO_MORE_TEAMS: return ERR_NO_MORE_HANDLES;
270 case B_BAD_PORT_ID: return ERR_INVALID_HANDLE;
271 case B_NO_MORE_PORTS: return ERR_NO_MORE_HANDLES;
272 case B_BAD_IMAGE_ID: return ERR_INVALID_HANDLE;
273 case B_NOT_AN_EXECUTABLE: return ERR_INVALID_BINARY;
274 default: return ERR_GENERAL;
278 static int newos2beos_err(int err)
280 if(err >= 0)
281 return err;
283 switch(err) {
284 case ERR_NO_MEMORY: return B_NO_MEMORY;
285 case ERR_IO_ERROR: return B_IO_ERROR;
286 case ERR_TIMED_OUT: return B_TIMED_OUT;
287 case ERR_NOT_ALLOWED: return B_NOT_ALLOWED;
288 case ERR_PERMISSION_DENIED: return B_PERMISSION_DENIED;
289 case ERR_INVALID_BINARY: return B_NOT_AN_EXECUTABLE;
291 case ERR_SEM_DELETED: return B_CANCELED;
292 case ERR_SEM_TIMED_OUT: return B_TIMED_OUT;
293 case ERR_SEM_OUT_OF_SLOTS: return B_NO_MORE_SEMS;
294 case ERR_INTERRUPTED: return B_INTERRUPTED;
295 default: return B_ERROR;
299 static int translation_open(dev_ident ident, dev_cookie *_cookie)
301 struct beos_device_node *node = (struct beos_device_node *)ident;
302 struct beos_device_cookie *cookie;
303 void *beos_cookie;
304 int err;
306 err = node->beos_hooks->open(node->name, 0, &beos_cookie);
307 if(err < 0)
308 return beos2newos_err(err);
310 cookie = kmalloc(sizeof(struct beos_device_cookie));
311 if(!cookie)
312 return ERR_NO_MEMORY;
314 cookie->node = node;
315 cookie->beos_cookie = beos_cookie;
316 cookie->pos = 0;
318 *_cookie = cookie;
320 return NO_ERROR;
323 static int translation_close(dev_cookie _cookie)
325 struct beos_device_cookie *cookie = _cookie;
326 int err;
328 err = cookie->node->beos_hooks->close(cookie->beos_cookie);
329 if(err < 0)
330 return beos2newos_err(err);
332 return NO_ERROR;
335 static int translation_freecookie(dev_cookie _cookie)
337 struct beos_device_cookie *cookie = _cookie;
338 int err;
340 err = cookie->node->beos_hooks->free(cookie->beos_cookie);
341 if(err < 0)
342 return beos2newos_err(err);
344 kfree(cookie);
346 return NO_ERROR;
349 static int translation_seek(dev_cookie _cookie, off_t pos, seek_type st)
351 struct beos_device_cookie *cookie = _cookie;
352 int err = NO_ERROR;
353 off_t nupos;
355 switch(st) {
356 case _SEEK_SET:
357 if(pos < 0)
358 pos = 0;
359 cookie->pos = pos;
360 break;
361 case _SEEK_CUR:
362 nupos = cookie->pos + pos;
363 if(nupos < 0)
364 nupos = 0;
365 cookie->pos = nupos;
366 break;
367 case _SEEK_END:
368 default:
369 err = ERR_INVALID_ARGS;
371 return err;
374 static int translation_ioctl(dev_cookie _cookie, int op, void *buf, size_t len)
376 struct beos_device_cookie *cookie = _cookie;
377 int err;
379 err = cookie->node->beos_hooks->control(cookie->beos_cookie, op, buf, len);
380 if(err < 0)
381 return beos2newos_err(err);
382 return NO_ERROR;
385 static ssize_t translation_read(dev_cookie _cookie, void *buf, off_t pos, ssize_t _len)
387 struct beos_device_cookie *cookie = _cookie;
388 int err;
389 bool update_cookie = false;
390 size_t len;
392 if(pos < 0) {
393 update_cookie = true;
394 pos = cookie->pos;
397 if(_len < 0)
398 len = 0;
399 else
400 len = _len;
402 err = cookie->node->beos_hooks->read(cookie->beos_cookie, pos, buf, &len);
403 if(err < 0)
404 return beos2newos_err(err);
406 if(update_cookie) {
407 cookie->pos += len;
409 return len;
412 static ssize_t translation_write(dev_cookie _cookie, const void *buf, off_t pos, ssize_t _len)
414 struct beos_device_cookie *cookie = _cookie;
415 int err;
416 bool update_cookie = false;
417 size_t len;
419 if(pos < 0) {
420 update_cookie = true;
421 pos = cookie->pos;
424 if(_len < 0)
425 len = 0;
426 else
427 len = _len;
429 err = cookie->node->beos_hooks->write(cookie->beos_cookie, pos, buf, &len);
430 if(err < 0)
431 return beos2newos_err(err);
433 if(update_cookie) {
434 cookie->pos += len;
436 return len;
439 static int translation_canpage(dev_ident ident)
441 return 0;
444 static ssize_t translation_readpage(dev_ident ident, iovecs *vecs, off_t pos)
446 return ERR_NOT_ALLOWED;
449 static ssize_t translation_writepage(dev_ident ident, iovecs *vecs, off_t pos)
451 return ERR_NOT_ALLOWED;
454 image_id beos_load_beos_driver(const char *name)
456 image_id id;
457 char path[SYS_MAX_PATH_LEN];
458 char **names;
459 int i;
461 int (*init_hardware)(void);
462 int (*init_driver)(void);
463 char **(*publish_devices)(void);
464 beos_device_hooks *(*find_device)(const char *name);
465 int *api_version;
467 sprintf(path, "/boot/addons/beosdev/%s", name);
469 id = elf_load_kspace(path, "_beos_");
470 if(id < 0)
471 return id;
473 api_version = (int *)elf_lookup_symbol(id, "api_version");
474 if(!api_version || *api_version != B_CUR_DRIVER_API_VERSION)
475 return ERR_INVALID_BINARY;
477 // dprintf("calling init_hardware\n");
479 init_hardware = (void *)elf_lookup_symbol(id, "init_hardware");
480 if(!init_hardware)
481 return ERR_INVALID_BINARY;
482 init_hardware();
484 // dprintf("done calling init_hardware\n");
486 // dprintf("calling init_driver\n");
488 init_driver = (void *)elf_lookup_symbol(id, "init_driver");
489 if(!init_driver)
490 return ERR_INVALID_BINARY;
491 init_driver();
493 // dprintf("done calling init_driver\n");
495 // dprintf("calling publish_devices\n");
497 publish_devices = (void *)elf_lookup_symbol(id, "publish_devices");
498 if(!publish_devices)
499 return ERR_INVALID_BINARY;
500 names = publish_devices();
502 // dprintf("done calling publish_devices\n");
504 find_device = (void *)elf_lookup_symbol(id, "find_device");
505 if(!publish_devices)
506 return ERR_INVALID_BINARY;
508 for(i=0; names[i]; i++) {
509 struct beos_device_node *node;
511 // dprintf("publishing name '%s'\n", names[i]);
513 node = kmalloc(sizeof(struct beos_device_node));
515 node->name = names[i];
516 node->beos_hooks = find_device(names[i]);
518 devfs_publish_device(names[i], node, &translation_hooks);
520 node->next = nodes;
521 nodes = node;
524 return id;
526 #else
528 int beos_layer_init(void)
530 return 0;
533 image_id beos_load_beos_driver(const char *name)
535 return ERR_GENERAL;
538 #endif