/branches/dynload/kernel/generic/include/lib/rd.h |
---|
66,16 → 66,18 |
#define RE_UNSUPPORTED 2 /* Non-supported image (e.g. wrong version) */ |
/** RAM disk header */ |
typedef struct { |
struct rd_header { |
uint8_t magic[RD_MAGIC_SIZE]; |
uint8_t version; |
uint8_t data_type; |
uint32_t header_size; |
uint64_t data_size; |
} rd_header; |
} __attribute__ ((packed)); |
extern int init_rd(rd_header * addr, size_t size); |
typedef struct rd_header rd_header_t; |
extern int init_rd(rd_header_t *addr, size_t size); |
#endif |
/** @} |
/branches/dynload/kernel/generic/include/ipc/ipc.h |
---|
205,6 → 205,8 |
#define IPC_MAX_PHONES 16 |
#include <synch/spinlock.h> |
#include <synch/mutex.h> |
#include <synch/waitq.h> |
struct answerbox; |
225,7 → 227,7 |
/** Structure identifying phone (in TASK structure) */ |
typedef struct { |
SPINLOCK_DECLARE(lock); |
mutex_t lock; |
link_t link; |
struct answerbox *callee; |
ipc_phone_state_t state; |
/branches/dynload/kernel/generic/src/main/kinit.c |
---|
189,7 → 189,7 |
/* It was the program loader and was registered */ |
} else { |
/* RAM disk image */ |
int rd = init_rd((rd_header *) init.tasks[i].addr, |
int rd = init_rd((rd_header_t *) init.tasks[i].addr, |
init.tasks[i].size); |
if (rd != RE_OK) |
/branches/dynload/kernel/generic/src/lib/rd.c |
---|
42,7 → 42,6 |
#include <mm/frame.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
#include <print.h> |
#include <align.h> |
static parea_t rd_parea; /**< Physical memory area for rd. */ |
52,7 → 51,7 |
* and information about the share is provided as sysinfo values to the userspace |
* tasks. |
*/ |
int init_rd(rd_header * header, size_t size) |
int init_rd(rd_header_t *header, size_t size) |
{ |
/* Identify RAM disk */ |
if ((header->magic[0] != RD_MAG0) || (header->magic[1] != RD_MAG1) || |
80,10 → 79,7 |
if ((hsize % FRAME_SIZE) || (dsize % FRAME_SIZE)) |
return RE_UNSUPPORTED; |
if (dsize % FRAME_SIZE) |
return RE_UNSUPPORTED; |
if (hsize > size) |
return RE_INVALID; |
/branches/dynload/kernel/generic/src/lib/elf.c |
---|
166,9 → 166,11 |
case PT_DYNAMIC: |
case PT_INTERP: |
interp = (char *)elf + entry->p_offset; |
if (memcmp(interp, ELF_INTERP_ZSTR, ELF_INTERP_ZLEN) != 0) { |
/* DO NOT COMMIT ME */ |
/*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR, |
ELF_INTERP_ZLEN) != 0) { |
return EE_UNSUPPORTED; |
} |
}*/ |
if ((flags & ELD_F_LOADER) == 0) { |
return EE_LOADER; |
} |
/branches/dynload/kernel/generic/src/ipc/sysipc.c |
---|
168,7 → 168,7 |
/* In case of forward, hangup the forwared phone, |
* not the originator |
*/ |
spinlock_lock(&answer->data.phone->lock); |
mutex_lock(&answer->data.phone->lock); |
spinlock_lock(&TASK->answerbox.lock); |
if (answer->data.phone->state == IPC_PHONE_CONNECTED) { |
list_remove(&answer->data.phone->link); |
175,7 → 175,7 |
answer->data.phone->state = IPC_PHONE_SLAMMED; |
} |
spinlock_unlock(&TASK->answerbox.lock); |
spinlock_unlock(&answer->data.phone->lock); |
mutex_unlock(&answer->data.phone->lock); |
} |
if (!olddata) |
/branches/dynload/kernel/generic/src/ipc/ipc.c |
---|
37,7 → 37,9 |
* First the answerbox, then the phone. |
*/ |
#include <synch/synch.h> |
#include <synch/spinlock.h> |
#include <synch/mutex.h> |
#include <synch/waitq.h> |
#include <synch/synch.h> |
#include <ipc/ipc.h> |
140,7 → 142,7 |
*/ |
void ipc_phone_connect(phone_t *phone, answerbox_t *box) |
{ |
spinlock_lock(&phone->lock); |
mutex_lock(&phone->lock); |
phone->state = IPC_PHONE_CONNECTED; |
phone->callee = box; |
149,7 → 151,7 |
list_append(&phone->link, &box->connected_phones); |
spinlock_unlock(&box->lock); |
spinlock_unlock(&phone->lock); |
mutex_unlock(&phone->lock); |
} |
/** Initialize a phone structure. |
158,7 → 160,7 |
*/ |
void ipc_phone_init(phone_t *phone) |
{ |
spinlock_initialize(&phone->lock, "phone_lock"); |
mutex_initialize(&phone->lock); |
phone->callee = NULL; |
phone->state = IPC_PHONE_FREE; |
atomic_set(&phone->active_calls, 0); |
261,9 → 263,9 |
{ |
answerbox_t *box; |
spinlock_lock(&phone->lock); |
mutex_lock(&phone->lock); |
if (phone->state != IPC_PHONE_CONNECTED) { |
spinlock_unlock(&phone->lock); |
mutex_unlock(&phone->lock); |
if (call->flags & IPC_CALL_FORWARDED) { |
IPC_SET_RETVAL(call->data, EFORWARD); |
_ipc_answer_free_call(call); |
278,7 → 280,7 |
box = phone->callee; |
_ipc_call(phone, box, call); |
spinlock_unlock(&phone->lock); |
mutex_unlock(&phone->lock); |
return 0; |
} |
297,11 → 299,11 |
answerbox_t *box; |
call_t *call; |
spinlock_lock(&phone->lock); |
mutex_lock(&phone->lock); |
if (phone->state == IPC_PHONE_FREE || |
phone->state == IPC_PHONE_HUNGUP || |
phone->state == IPC_PHONE_CONNECTING) { |
spinlock_unlock(&phone->lock); |
mutex_unlock(&phone->lock); |
return -1; |
} |
box = phone->callee; |
320,7 → 322,7 |
} |
phone->state = IPC_PHONE_HUNGUP; |
spinlock_unlock(&phone->lock); |
mutex_unlock(&phone->lock); |
return 0; |
} |
449,7 → 451,7 |
while (!list_empty(&TASK->answerbox.connected_phones)) { |
phone = list_get_instance(TASK->answerbox.connected_phones.next, |
phone_t, link); |
if (!spinlock_trylock(&phone->lock)) { |
if (SYNCH_FAILED(mutex_trylock(&phone->lock))) { |
spinlock_unlock(&TASK->answerbox.lock); |
DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD); |
goto restart_phones; |
460,7 → 462,7 |
phone->state = IPC_PHONE_SLAMMED; |
list_remove(&phone->link); |
spinlock_unlock(&phone->lock); |
mutex_unlock(&phone->lock); |
} |
/* Answer all messages in 'calls' and 'dispatched_calls' queues */ |
535,7 → 537,10 |
/* Print opened phones & details */ |
printf("PHONE:\n"); |
for (i = 0; i < IPC_MAX_PHONES; i++) { |
spinlock_lock(&task->phones[i].lock); |
if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) { |
printf("%d: mutex busy\n", i); |
continue; |
} |
if (task->phones[i].state != IPC_PHONE_FREE) { |
printf("%d: ", i); |
switch (task->phones[i].state) { |
560,7 → 565,7 |
printf("active: %d\n", |
atomic_get(&task->phones[i].active_calls)); |
} |
spinlock_unlock(&task->phones[i].lock); |
mutex_unlock(&task->phones[i].lock); |
} |
579,7 → 584,7 |
} |
/* Print answerbox - calls */ |
printf("ABOX - DISPATCHED CALLS:\n"); |
for (tmp=task->answerbox.dispatched_calls.next; |
for (tmp = task->answerbox.dispatched_calls.next; |
tmp != &task->answerbox.dispatched_calls; |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
/branches/dynload/kernel/arch/amd64/include/memstr.h |
---|
35,110 → 35,13 |
#ifndef KERN_amd64_MEMSTR_H_ |
#define KERN_amd64_MEMSTR_H_ |
/** Copy memory |
* |
* Copy a given number of bytes (3rd argument) |
* from the memory location defined by 2nd argument |
* to the memory location defined by 1st argument. |
* The memory areas cannot overlap. |
* |
* @param dst Destination |
* @param src Source |
* @param cnt Number of bytes |
* @return Destination |
*/ |
static inline void * memcpy(void * dst, const void * src, size_t cnt) |
{ |
unative_t d0, d1, d2; |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
asm volatile( |
"rep movsq\n\t" |
"movq %4, %%rcx\n\t" |
"andq $7, %%rcx\n\t" |
"jz 1f\n\t" |
"rep movsb\n\t" |
"1:\n" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
: "0" ((unative_t)(cnt / 8)), "g" ((unative_t)cnt), "1" ((unative_t) dst), "2" ((unative_t) src) |
: "memory"); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
return dst; |
} |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
/** Compare memory regions for equality |
* |
* Compare a given number of bytes (3rd argument) |
* at memory locations defined by 1st and 2nd argument |
* for equality. If bytes are equal function returns 0. |
* |
* @param src Region 1 |
* @param dst Region 2 |
* @param cnt Number of bytes |
* @return Zero if bytes are equal, non-zero otherwise |
*/ |
static inline int memcmp(const void * src, const void * dst, size_t cnt) |
{ |
unative_t d0, d1, d2; |
unative_t ret; |
asm ( |
"repe cmpsb\n\t" |
"je 1f\n\t" |
"movq %3, %0\n\t" |
"addq $1, %0\n\t" |
"1:\n" |
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2) |
: "0" (0), "1" (src), "2" (dst), "3" ((unative_t)cnt) |
); |
return ret; |
} |
/** Fill memory with words |
* Fill a given number of words (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of words |
* @param x Value to fill |
*/ |
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
unative_t d0, d1; |
asm volatile ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((unative_t)cnt), "2" (x) |
: "memory" |
); |
} |
/** Fill memory with bytes |
* Fill a given number of bytes (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of bytes |
* @param x Value to fill |
*/ |
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
unative_t d0, d1; |
asm volatile ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((unative_t)cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/** @} |
/branches/dynload/kernel/arch/amd64/src/asm_utils.S |
---|
65,6 → 65,8 |
.global get_cycle |
.global read_efer_flag |
.global set_efer_flag |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
71,6 → 73,14 |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
# Wrapper for generic memsetb |
memsetb: |
jmp _memsetb |
# Wrapper for generic memsetw |
memsetw: |
jmp _memsetw |
#define MEMCPY_DST %rdi |
#define MEMCPY_SRC %rsi |
#define MEMCPY_SIZE %rdx |
/branches/dynload/kernel/arch/mips32/include/atomic.h |
---|
63,7 → 63,7 |
" sc %0, %1\n" |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
" nop\n" |
: "=r" (tmp), "=m" (val->count), "=r" (v) |
: "=&r" (tmp), "=m" (val->count), "=&r" (v) |
: "i" (i), "i" (0) |
); |
/branches/dynload/kernel/arch/ia32/include/memstr.h |
---|
35,116 → 35,13 |
#ifndef KERN_ia32_MEMSTR_H_ |
#define KERN_ia32_MEMSTR_H_ |
/** Copy memory |
* |
* Copy a given number of bytes (3rd argument) |
* from the memory location defined by 2nd argument |
* to the memory location defined by 1st argument. |
* The memory areas cannot overlap. |
* |
* @param dst Destination |
* @param src Source |
* @param cnt Number of bytes |
* @return Destination |
*/ |
static inline void * memcpy(void * dst, const void * src, size_t cnt) |
{ |
unative_t d0, d1, d2; |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
asm volatile( |
/* copy all full dwords */ |
"rep movsl\n\t" |
/* load count again */ |
"movl %4, %%ecx\n\t" |
/* ecx = ecx mod 4 */ |
"andl $3, %%ecx\n\t" |
/* are there last <=3 bytes? */ |
"jz 1f\n\t" |
/* copy last <=3 bytes */ |
"rep movsb\n\t" |
/* exit from asm block */ |
"1:\n" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
: "0" ((unative_t) (cnt / 4)), "g" ((unative_t) cnt), "1" ((unative_t) dst), "2" ((unative_t) src) |
: "memory"); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
return dst; |
} |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
/** Compare memory regions for equality |
* |
* Compare a given number of bytes (3rd argument) |
* at memory locations defined by 1st and 2nd argument |
* for equality. If bytes are equal function returns 0. |
* |
* @param src Region 1 |
* @param dst Region 2 |
* @param cnt Number of bytes |
* @return Zero if bytes are equal, non-zero otherwise |
*/ |
static inline int memcmp(const void * src, const void * dst, size_t cnt) |
{ |
uint32_t d0, d1, d2; |
int ret; |
asm ( |
"repe cmpsb\n\t" |
"je 1f\n\t" |
"movl %3, %0\n\t" |
"addl $1, %0\n\t" |
"1:\n" |
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2) |
: "0" (0), "1" ((unative_t) src), "2" ((unative_t) dst), "3" ((unative_t) cnt) |
); |
return ret; |
} |
/** Fill memory with words |
* Fill a given number of words (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of words |
* @param x Value to fill |
*/ |
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
/** Fill memory with bytes |
* Fill a given number of bytes (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of bytes |
* @param x Value to fill |
*/ |
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia32/src/asm.S |
---|
37,6 → 37,8 |
.global paging_on |
.global enable_l_apic_in_msr |
.global interrupt_handlers |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_from_uspace_failover_address |
44,6 → 46,15 |
.global memcpy_to_uspace_failover_address |
# Wrapper for generic memsetb |
memsetb: |
jmp _memsetb |
# Wrapper for generic memsetw |
memsetw: |
jmp _memsetw |
#define MEMCPY_DST 4 |
#define MEMCPY_SRC 8 |
#define MEMCPY_SIZE 12 |