-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| #include <errno.h> | ||
| #include <core/debug.h> | ||
| #include <core/partition.h> | ||
| #include <core/hypercall.h> | ||
|
|
||
| #include "event.h" | ||
| #include "gdt.h" | ||
|
|
||
| #define PARTITION_ID(cs) (((cs >> 3) - 4 ) / 2) | ||
|
|
||
| /* | ||
| * Define the hypercall handler function | ||
| */ | ||
|
|
||
| INTERRUPT_HANDLER_hypercall(hypercall_gate) | ||
| { | ||
| pok_hypercall_info_t hypercall_info; | ||
| pok_ret_t hypercall_ret; | ||
| pok_hypercall_args_t* hypercall_args; | ||
| pok_hypercall_id_t hypercall_id; | ||
|
|
||
| hypercall_info.partition = PARTITION_ID (frame->cs); | ||
| hypercall_info.base_addr = pok_partitions[hypercall_info.partition].base_addr; | ||
| hypercall_info.thread = POK_SCHED_CURRENT_THREAD; | ||
|
|
||
| hypercall_args = (pok_hypercall_args_t * ) (frame->ebx + hypercall_info.base_addr); | ||
|
|
||
| hypercall_id = (pok_hypercall_id_t) frame->eax; | ||
|
|
||
| if (POK_CHECK_PTR_IN_PARTITION(hypercall_info.partition, hypercall_args) == 0) | ||
| { | ||
| hypercall_ret = POK_ERRNO_EINVAL; | ||
| } | ||
| else | ||
| { | ||
| // perform the hypercall; | ||
| hypercall_ret = pok_core_hypercall ( hypercall_id, hypercall_args, & hypercall_info); | ||
| } | ||
| /* | ||
| * put the return value in eax register | ||
| */ | ||
| asm ( "movl %0, %%eax \n" | ||
| : | ||
| : "m" (hypercall_ret)); | ||
| } | ||
|
|
||
| /* | ||
| * Init Hypercall system | ||
| */ | ||
|
|
||
| pok_ret_t pok_hypercall_init() | ||
| { | ||
| pok_idt_set_gate (POK_HYPERCALL_INT_NUMBER, | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Yourens
Author
Owner
|
||
| GDT_CORE_CODE_SEGMENT << 3, | ||
| (uint32_t) hypercall_gate, | ||
| IDTE_INTERRUPT, | ||
| 3); | ||
| return (POK_ERRNO_OK); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
|
|
||
| #include <bsp.h> | ||
| #include <types.h> | ||
| #include <libc.h> | ||
| #include <arch/x86/ioports.h> | ||
| #include <arch/x86/pci.h> | ||
|
|
||
| #include <errno.h> | ||
| #include <core/debug.h> | ||
| #include <core/hypercall.h> | ||
| #include <core/partition.h> | ||
| #include <core/thread.h> | ||
| #include <core/lockobj.h> | ||
| #include <core/time.h> | ||
| #include <core/error.h> | ||
|
|
||
| #include <middleware/port.h> | ||
|
|
||
|
|
||
|
|
||
| pok_ret_t pok_core_hypercall (const pok_hypercall_id_t hypercall_id, | ||
| const pok_hypercall_args_t* args, | ||
| const pok_hypercall_info_t* infos) | ||
| { | ||
| switch (hypercall_id) | ||
| { | ||
| #if defined (POK_NEEDS_CONSOLE) || defined (POK_NEEDS_DEBUG) | ||
| case POK_HYPERCALL_CONSWRITE: | ||
| POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg1 + infos->base_addr) | ||
| if (pok_cons_write ((const char*)args->arg1 + infos->base_addr, args->arg2)) | ||
| { | ||
| return POK_ERRNO_OK; | ||
| } | ||
| else | ||
| { | ||
| return POK_ERRNO_EINVAL; | ||
| } | ||
| break; | ||
| #endif | ||
|
|
||
| #ifdef POK_NEEDS_X86_VMM | ||
| /** | ||
| * This shall register an irq handler with the meta_handler for the | ||
| * requested interrupt number. | ||
| * arg1: vector nubmer, | ||
| * arg2: handler/callback function | ||
| */ | ||
| case POK_HYPERCALL_IRQ_REGISTER_HANDLER: | ||
| POK_CHECK_PTR_OR_RETURN(infos->partition, args->arg2 + infos->base_addr) | ||
| /* arg1 is just a number, arg2 is a pointer to a function in the | ||
| * partition, therefore the partitions base_addr must be added to become | ||
| * a valid pointer for the kernel. | ||
| */ | ||
| return pok_bsp_irq_register_hw (args->arg1, | ||
| (void(*)(unsigned, void*)) ((args->arg2 + infos->base_addr)) ); | ||
| break; | ||
|
|
||
| case POK_HYPERCALL_IRQ_UNREGISTER_HANDLER: | ||
| return pok_bsp_irq_unregister_hw (args->arg1); | ||
| break; | ||
| /* enable/disable interrupt delivery to a partition */ | ||
| case POK_HYPERCALL_IRQ_PARTITION_ENABLE: | ||
| return pok_bsp_irq_partition_enable (args->arg1); | ||
| break; | ||
| case POK_HYPERCALL_IRQ_PARTITION_DISABLE: | ||
| return pok_bsp_irq_partition_disable (args->arg1); | ||
| break; | ||
| case POK_HYPERCALL_IRQ_PARTITION_ACK: | ||
| return pok_bsp_irq_partition_ack(args->arg1); | ||
| break; | ||
| #endif /* POK_NEEDS_X86_VMM */ | ||
| default: | ||
| #ifdef POK_NEEDS_ERROR_HANDLING | ||
| pok_error_declare( POK_ERROR_KIND_ILLEGAL_REQUEST); | ||
| pok_sched_activate_error_thread (); | ||
| #else | ||
| #ifdef POK_NEEDS_DEBUG | ||
| printf("Tried to use hypercall %d\n", hypercall_id); | ||
| #endif | ||
| POK_FATAL ("Unknown hypercall"); | ||
| #endif | ||
| break; | ||
| } | ||
| return POK_ERRNO_EINVAL; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #ifndef __POK_HYPERCALL_H__ | ||
| #define __POK_HYPERCALL_H__ | ||
|
|
||
| #include <types.h> | ||
| #include <errno.h> | ||
|
|
||
| typedef enum | ||
| { | ||
| POK_HYPERCALL_CONSWRITE =10, | ||
| POK_HYPERCALL_INT_NUMBER =24, | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Yourens
Author
Owner
|
||
| /* Register an irq handler from a partition */ | ||
| POK_HYPERCALL_IRQ_REGISTER_HANDLER = 25, | ||
| POK_HYPERCALL_IRQ_UNREGISTER_HANDLER = 26, | ||
| /* enable/disable interrupt delivery to a partition */ | ||
| POK_HYPERCALL_IRQ_PARTITION_ENABLE = 27, | ||
| POK_HYPERCALL_IRQ_PARTITION_DISABLE = 28, | ||
| POK_HYPERCALL_IRQ_PARTITION_ACK = 29, | ||
| } pok_hypercall_id_t; | ||
|
|
||
| typedef struct | ||
| { | ||
| pok_partition_id_t partition; | ||
| uint32_t thread; | ||
| uint32_t base_addr; | ||
| }pok_hypercall_info_t; | ||
|
|
||
| typedef struct | ||
| { | ||
| uint32_t nargs; | ||
| uint32_t arg1; | ||
| uint32_t arg2; | ||
| uint32_t arg3; | ||
| uint32_t arg4; | ||
| uint32_t arg5; | ||
| } pok_hypercall_args_t; | ||
|
|
||
| pok_ret_t pok_core_hypercall(const pok_hypercall_id_t hypercall_id, | ||
| const pok_hypercall_args_t* args, | ||
| const pok_hypercall_info_t* infos); | ||
|
|
||
| pok_ret_t pok_hypercall_init(); | ||
| #endif /* __POK_HYPERCALL_H__ */ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
|
|
||
| #include <core/syscall.h> | ||
| #include <types.h> | ||
|
|
||
| pok_ret_t pok_do_hypercall (pok_syscall_id_t syscall_id, pok_syscall_args_t* args) | ||
This comment has been minimized.
Sorry, something went wrong.
phipse
|
||
| { | ||
| pok_ret_t ret; | ||
| uint32_t args_addr; | ||
| uint32_t id; | ||
|
|
||
| args_addr = (uint32_t) args; | ||
| id = (uint32_t) syscall_id; | ||
|
|
||
| asm volatile ( "movl %1,%%eax \n\t" | ||
| "movl %2,%%ebx \n\t" | ||
| "int $24 \n\t" | ||
| "movl %%eax, %0" | ||
| :"=g"(ret) | ||
| :"g"(id), "g"(args_addr) | ||
| : "%eax" , "%ebx" | ||
| ); | ||
| return ret; | ||
| } | ||
|
|
||
You are not allowed to use the first 32 lines in the IDT! These are reserved by INTEL.
More on interrupts:
http://www.brokenthorn.com/Resources/OSDev15.html