2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
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>
19 // contains a bunch of beos defines
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
;
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
;
62 /* our device hooks structure */
63 struct dev_calls translation_hooks
= {
66 &translation_freecookie
,
72 &translation_readpage
,
73 &translation_writepage
76 isa_module_info isa
= {
78 { "isa", 0, NULL
}, /* minfo */
79 (void *)unhandled_isa_call
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
99 { B_ISA_MODULE_NAME
, &isa
},
103 int beos_layer_init(void)
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
)
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();
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");
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
)
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
)
196 dprintf("get_module: called on '%s'\n", path
);
197 for(m
= modules
; m
->name
; m
++) {
198 if(!strcmp(path
, m
->name
)) {
206 int _beos_put_module(const char *path
)
208 dprintf("put_module: called on '%s'\n", path
);
212 static uint8
read8(int port
)
217 static void write8(int port
, uint8 data
)
219 // dprintf("w8 0x%x, 0x%x\n", port, data);
223 static uint16
read16(int port
)
228 static void write16(int port
, uint16 data
)
230 // dprintf("w16 0x%x, 0x%x\n", port, data);
234 static uint32
read32(int port
)
239 static void write32(int port
, uint32 data
)
241 // dprintf("w32 0x%x, 0x%x\n", port, data);
245 static void unhandled_isa_call(void)
247 panic("call into unhandled isa function\n");
250 static int beos2newos_err(int 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
)
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
;
306 err
= node
->beos_hooks
->open(node
->name
, 0, &beos_cookie
);
308 return beos2newos_err(err
);
310 cookie
= kmalloc(sizeof(struct beos_device_cookie
));
312 return ERR_NO_MEMORY
;
315 cookie
->beos_cookie
= beos_cookie
;
323 static int translation_close(dev_cookie _cookie
)
325 struct beos_device_cookie
*cookie
= _cookie
;
328 err
= cookie
->node
->beos_hooks
->close(cookie
->beos_cookie
);
330 return beos2newos_err(err
);
335 static int translation_freecookie(dev_cookie _cookie
)
337 struct beos_device_cookie
*cookie
= _cookie
;
340 err
= cookie
->node
->beos_hooks
->free(cookie
->beos_cookie
);
342 return beos2newos_err(err
);
349 static int translation_seek(dev_cookie _cookie
, off_t pos
, seek_type st
)
351 struct beos_device_cookie
*cookie
= _cookie
;
362 nupos
= cookie
->pos
+ pos
;
369 err
= ERR_INVALID_ARGS
;
374 static int translation_ioctl(dev_cookie _cookie
, int op
, void *buf
, size_t len
)
376 struct beos_device_cookie
*cookie
= _cookie
;
379 err
= cookie
->node
->beos_hooks
->control(cookie
->beos_cookie
, op
, buf
, len
);
381 return beos2newos_err(err
);
385 static ssize_t
translation_read(dev_cookie _cookie
, void *buf
, off_t pos
, ssize_t _len
)
387 struct beos_device_cookie
*cookie
= _cookie
;
389 bool update_cookie
= false;
393 update_cookie
= true;
402 err
= cookie
->node
->beos_hooks
->read(cookie
->beos_cookie
, pos
, buf
, &len
);
404 return beos2newos_err(err
);
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
;
416 bool update_cookie
= false;
420 update_cookie
= true;
429 err
= cookie
->node
->beos_hooks
->write(cookie
->beos_cookie
, pos
, buf
, &len
);
431 return beos2newos_err(err
);
439 static int translation_canpage(dev_ident ident
)
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
)
457 char path
[SYS_MAX_PATH_LEN
];
461 int (*init_hardware
)(void);
462 int (*init_driver
)(void);
463 char **(*publish_devices
)(void);
464 beos_device_hooks
*(*find_device
)(const char *name
);
467 sprintf(path
, "/boot/addons/beosdev/%s", name
);
469 id
= elf_load_kspace(path
, "_beos_");
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");
481 return ERR_INVALID_BINARY
;
484 // dprintf("done calling init_hardware\n");
486 // dprintf("calling init_driver\n");
488 init_driver
= (void *)elf_lookup_symbol(id
, "init_driver");
490 return ERR_INVALID_BINARY
;
493 // dprintf("done calling init_driver\n");
495 // dprintf("calling publish_devices\n");
497 publish_devices
= (void *)elf_lookup_symbol(id
, "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");
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
);
528 int beos_layer_init(void)
533 image_id
beos_load_beos_driver(const char *name
)