/kernel/trunk/generic/include/ddi/ddi.h |
---|
39,6 → 39,8 |
/* |
* Interface to be implemented by all architectures. |
*/ |
extern __native ddi_int_control_arch(__native enable, __native *flags); |
extern __native ddi_int_control(__native enable, __native *flags); |
extern int ddi_enable_iospace_arch(task_t *task, __address ioaddr, size_t size); |
#endif |
/kernel/trunk/generic/include/security/cap.h |
---|
57,6 → 57,11 |
*/ |
#define CAP_IO_MANAGER (1<<2) |
/** |
* CAP_INT_CONTROL allows its holder to disable interrupts |
*/ |
#define CAP_INT_CONTROL (1<<3) |
typedef __u32 cap_t; |
extern void cap_set(task_t *t, cap_t caps); |
/kernel/trunk/generic/include/syscall/syscall.h |
---|
32,6 → 32,7 |
typedef enum { |
SYS_IO = 0, |
SYS_TLS_SET = 1, /* Hardcoded in AMD64,IA32 uspace - psthread.S */ |
SYS_INT_CONTROL = 2, /* Hardcoded in all SYSCALL handlers */ |
SYS_THREAD_CREATE, |
SYS_THREAD_EXIT, |
SYS_FUTEX_SLEEP, |
/kernel/trunk/generic/src/ddi/ddi.c |
---|
194,3 → 194,11 |
copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t)); |
return (__native) ddi_enable_iospace((task_id_t) arg.task_id, (__address) arg.ioaddr, (size_t) arg.size); |
} |
__native ddi_int_control(__native enable, __native *flags) |
{ |
if (! cap_get(TASK) & CAP_INT_CONTROL) |
return EPERM; |
return ddi_int_control_arch(enable, flags); |
} |
/kernel/trunk/generic/src/syscall/syscall.c |
---|
64,6 → 64,11 |
return as_remap(AS, (__address) address, size, 0); |
} |
static __native sys_int_control(int enable) |
{ |
panic("Not implemented."); |
} |
/** Dispatch system call */ |
__native syscall_handler(__native a1, __native a2, __native a3, |
__native a4, __native id) |
77,6 → 82,7 |
syshandler_t syscall_table[SYSCALL_END] = { |
sys_io, |
sys_tls_set, |
sys_int_control, |
sys_thread_create, |
sys_thread_exit, |
sys_futex_sleep_timeout, |
/kernel/trunk/arch/amd64/include/cpu.h |
---|
29,6 → 29,7 |
#ifndef __amd64_CPU_H__ |
#define __amd64_CPU_H__ |
#define RFLAGS_IF (1 << 9) |
#define RFLAGS_RF (1 << 16) |
#define EFER_MSR_NUM 0xc0000080 |
/kernel/trunk/arch/amd64/src/ddi/ddi.c |
---|
34,6 → 34,7 |
#include <mm/slab.h> |
#include <arch/pm.h> |
#include <errno.h> |
#include <arch/cpu.h> |
/** Enable I/O space range for task. |
* |
90,3 → 91,17 |
return 0; |
} |
/** Enable/disable interrupts form syscall |
* |
* @param enable If non-zero, interrupts are enabled, otherwise disabled |
* @param flags CP0 flags register |
*/ |
__native ddi_int_control_arch(__native enable, __native *flags) |
{ |
if (enable) |
*flags |= RFLAGS_IF; |
else |
*flags &= ~RFLAGS_IF; |
return 0; |
} |
/kernel/trunk/arch/amd64/src/asm_utils.S |
---|
243,7 → 243,12 |
sti |
movq %r9, %rcx # Exchange last parameter as a third |
cmp $2, %r8 # Is this SYS_INT_CONTROL |
je sys_int_ctrl |
call syscall_handler |
sys_end: |
cli # We will be touching stack pointer |
popq %r11 |
251,6 → 256,12 |
movq 0(%rsp), %rsp |
sysretq |
sys_int_ctrl: |
mov %rsp, %rsi # Pointer to flags |
call ddi_int_control |
jmp sys_end |
.data |
.global interrupt_handler_size |
/kernel/trunk/arch/amd64/src/mm/page.c |
---|
168,7 → 168,7 |
page = read_cr2(); |
if (!as_page_fault(page)) { |
print_info_errcode(n, istate); |
printf("Page fault address: %Q\n", page); |
printf("Page fault address: %llX\n", page); |
panic("page fault\n"); |
} |
} |
/kernel/trunk/arch/mips32/src/start.S |
---|
251,10 → 251,15 |
sw $t2,SS_STATUS($sp) |
mtc0 $t0, $status |
li $t4, 2 # SYS_INT_CONTROL |
beq $t4, $v0, sysc_int_control |
nop |
# CALL Syscall handler |
jal syscall_handler |
sw $v0, SS_ARG4($sp) # save v0 - arg4 to stack |
sysc_exit: |
# restore status |
mfc0 $t0, $status |
lw $t1,SS_STATUS($sp) |
275,6 → 280,13 |
eret |
sysc_int_control: |
jal ddi_int_control |
addi $a1, $sp, SS_STATUS |
j sysc_exit |
nop |
tlb_refill_handler: |
KERNEL_STACK_TO_K0 |
sub $k0, REGISTER_SPACE |
/kernel/trunk/arch/mips32/src/ddi/ddi.c |
---|
30,6 → 30,9 |
#include <proc/task.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <security/cap.h> |
#include <arch.h> |
#include <arch/cp0.h> |
/** Enable I/O space range for task. |
* |
45,3 → 48,17 |
{ |
return 0; |
} |
/** Enable/disable interrupts form syscall |
* |
* @param enable If non-zero, interrupts are enabled, otherwise disabled |
* @param flags CP0 flags register |
*/ |
__native ddi_int_control_arch(__native enable, __native *flags) |
{ |
if (enable) |
*flags |= cp0_status_ie_enabled_bit; |
else |
*flags &= ~cp0_status_ie_enabled_bit; |
return 0; |
} |
/kernel/trunk/arch/ia32/include/cpu.h |
---|
33,6 → 33,7 |
#include <arch/pm.h> |
#include <arch/asm.h> |
#define EFLAGS_IF (1 << 9) |
#define EFLAGS_RF (1 << 16) |
struct cpu_arch { |
/kernel/trunk/arch/ia32/src/asm.S |
---|
86,7 → 86,7 |
# The handlers setup data segment registers |
# and call exc_dispatch(). |
# |
#define INTERRUPT_ALIGN 64 |
#define INTERRUPT_ALIGN 128 |
.macro handler i n |
.ifeq \i-0x30 # Syscall handler |
108,7 → 108,11 |
movw %ax,%es |
sti |
cmp $2, %edi # Is this SYS_INT_CONTROL? |
je sys_int_ctrl |
call syscall_handler # syscall_handler(ax,cx,dx,si,di) |
sysc_end: |
cli |
addl $20, %esp # clean-up of parameters |
119,6 → 123,12 |
CLEAR_NT_FLAG |
iret |
sys_int_ctrl: # Interrupt control |
mov %esp, %eax |
add $44, %eax |
mov %eax, 4(%esp) # Pointer to flags - 2nd argument |
call ddi_int_control |
jmp sysc_end |
.else |
/* |
* This macro distinguishes between two versions of ia32 exceptions. |
/kernel/trunk/arch/ia32/src/ddi/ddi.c |
---|
34,6 → 34,7 |
#include <mm/slab.h> |
#include <arch/pm.h> |
#include <errno.h> |
#include <arch/cpu.h> |
/** Enable I/O space range for task. |
* |
90,3 → 91,17 |
return 0; |
} |
/** Enable/disable interrupts form syscall |
* |
* @param enable If non-zero, interrupts are enabled, otherwise disabled |
* @param flags CP0 flags register |
*/ |
__native ddi_int_control_arch(__native enable, __native *flags) |
{ |
if (enable) |
*flags |= EFLAGS_IF; |
else |
*flags &= ~EFLAGS_IF; |
return 0; |
} |