Reimplemented atomic destructive read. Revised irq control capabilities.

This commit is contained in:
Bahadir Balban
2009-12-13 18:49:35 +02:00
parent c7069a8e8e
commit 0c4bd69357
3 changed files with 17 additions and 22 deletions

View File

@@ -1,26 +1,11 @@
#ifndef __L4LIB_ARCH_IRQ_H__ #ifndef __L4LIB_ARCH_IRQ_H__
#define __L4LIB_ARCH_IRQ_H__ #define __L4LIB_ARCH_IRQ_H__
/* /*
* Destructive atomic-read. * Destructive atomic-read.
* *
* Write 0 to byte at @location as its contents are read back. * Write 0 to byte at @location as its contents are read back.
*/ */
static inline char l4_atomic_dest_readb(void *location) char l4_atomic_dest_readb(void *location);
{
unsigned char zero = 0; /* Input */
unsigned char val; /* Output */
char *loc = location; /* Both input and output */
__asm__ __volatile__ (
"swpb %1, %3, [%0] \n"
: "=r" (*loc), "=r" (val)
: "r" (*loc), "r" (zero)
);
return val;
}
#endif #endif

View File

@@ -63,4 +63,10 @@ BEGIN_PROC(__l4_mutex_unlock)
mov pc, lr mov pc, lr
END_PROC(__l4_mutex_unlock) END_PROC(__l4_mutex_unlock)
BEGIN_PROC(l4_atomic_dest_readb)
mov r1, r0 @ Move byte address to r1
mov r2, #0 @ Move 0 to r2
swpb r0, r2, [r1] @ Write 0 to byte location, while reading its value to r0
mov pc, lr @ Return byte location value
END_PROC(l4_atomic_dest_readb)

View File

@@ -726,6 +726,10 @@ struct capability *cap_match_irqctrl(struct capability *cap,
if (!(cap->access & CAP_IRQCTRL_REGISTER)) if (!(cap->access & CAP_IRQCTRL_REGISTER))
return 0; return 0;
break; break;
case IRQ_CONTROL_WAIT:
if (!(cap->access & CAP_IRQCTRL_WAIT))
return 0;
break;
default: default:
/* We refuse to accept anything else */ /* We refuse to accept anything else */
return 0; return 0;
@@ -892,13 +896,13 @@ int cap_irq_check(struct ktcb *registrant, unsigned int req,
return -ENOCAP; return -ENOCAP;
/* /*
* Find the device capability and * If it is an irq registration, find the device
* check that it allows irq registration * capability and check that it allows irq registration.
*/ */
if (!cap_find(current, cap_match_devmem, if (req == IRQ_CONTROL_REGISTER)
&args, CAP_TYPE_MAP_PHYSMEM)) if (!cap_find(current, cap_match_devmem,
return -ENOCAP; &args, CAP_TYPE_MAP_PHYSMEM))
return -ENOCAP;
return 0; return 0;
} }