initial support for a commpage, which is a chunk of memory in high kernel space with user readonly permissions.
The first use is to let the kernel decide what the preferred syscall mechanism is at boot time and copy the appropriate user space code there. Can be used for routines the kernel can decide best how to use (memcpy, some timing routines, etc). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20161 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
badc7b674e
commit
1cbf8f4b3c
23
headers/os/kernel/arch/x86/commpage.h
Normal file
23
headers/os/kernel/arch/x86/commpage.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2007, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef __OS_KERNEL_ARCH_x86_COMMPAGE_H
|
||||
#define __OS_KERNEL_ARCH_x86_COMMPAGE_H
|
||||
|
||||
/* some systemwide commpage constants, used in the kernel and libroot */
|
||||
|
||||
/* be careful what you put here, this file is included from assembly */
|
||||
#define COMMPAGE_ENTRY_MAGIC 0
|
||||
#define COMMPAGE_ENTRY_VERSION 1
|
||||
#define COMMPAGE_ENTRY_SYSCALL 2
|
||||
|
||||
#define USER_COMMPAGE_ADDR (0xffff0000)
|
||||
#define COMMPAGE_SIZE (0x8000)
|
||||
#define TABLE_ENTRIES 64
|
||||
|
||||
#define COMMPAGE_SIGNATURE 'COMM'
|
||||
#define COMMPAGE_VERSION 1
|
||||
|
||||
#endif
|
||||
|
12
headers/private/kernel/arch/x86/commpage.h
Normal file
12
headers/private/kernel/arch/x86/commpage.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2007, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_ARCH_x86_COMMPAGE_H
|
||||
#define _KERNEL_ARCH_x86_COMMPAGE_H
|
||||
|
||||
|
||||
status_t commpage_init(void);
|
||||
|
||||
#endif
|
||||
|
@ -31,6 +31,8 @@ KernelStaticLibrary libx86 :
|
||||
apm.cpp
|
||||
bios.cpp
|
||||
cpuid.S
|
||||
commpage.c
|
||||
syscall.S
|
||||
|
||||
generic_vm_physical_page_mapper.cpp
|
||||
:
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/x86/selector.h>
|
||||
#include <boot/kernel_args.h>
|
||||
#include <arch/x86/commpage.h>
|
||||
|
||||
#include "interrupts.h"
|
||||
|
||||
@ -505,6 +506,9 @@ arch_cpu_init_post_vm(kernel_args *args)
|
||||
// setup SSE2/3 support
|
||||
init_sse();
|
||||
|
||||
// initialize the commpage support
|
||||
commpage_init();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
74
src/system/kernel/arch/x86/commpage.c
Normal file
74
src/system/kernel/arch/x86/commpage.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2007, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#include <vm.h>
|
||||
#include <arch/x86/commpage.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <os/kernel/arch/x86/commpage.h>
|
||||
|
||||
static area_id comm_area;
|
||||
static area_id user_comm_area;
|
||||
static unsigned long *comm_ptr;
|
||||
static unsigned long *user_comm_ptr;
|
||||
static void *next_comm_addr;
|
||||
|
||||
// user syscall assembly stub
|
||||
extern void _user_syscall_int(void);
|
||||
extern unsigned int _user_syscall_int_end;
|
||||
|
||||
static inline
|
||||
addr_t commpage_ptr_to_user_ptr(const void *ptr)
|
||||
{
|
||||
return ((addr_t)ptr) + ((addr_t)user_comm_ptr - (addr_t)comm_ptr);
|
||||
}
|
||||
|
||||
static
|
||||
status_t initialize_commpage_syscall(void)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
// for now, we're hard coded to use the legacy method (int 99)
|
||||
len = (size_t)((void *)&_user_syscall_int_end - (void *)&_user_syscall_int);
|
||||
memcpy(next_comm_addr, &_user_syscall_int, len);
|
||||
|
||||
// fill in the table entry
|
||||
comm_ptr[COMMPAGE_ENTRY_SYSCALL] = commpage_ptr_to_user_ptr(next_comm_addr);
|
||||
next_comm_addr = (void *)((addr_t)next_comm_addr + ROUNDUP(len, 4));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
commpage_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// create a read/write kernel area
|
||||
comm_area = create_area("commpage", (void **)&comm_ptr, B_ANY_ADDRESS, COMMPAGE_SIZE, B_FULL_LOCK,
|
||||
B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA);
|
||||
|
||||
// clone it at a fixed address with user read/only permissions
|
||||
user_comm_ptr = (void *)USER_COMMPAGE_ADDR;
|
||||
user_comm_area = clone_area("user_commpage", (void **)&user_comm_ptr, B_EXACT_ADDRESS,
|
||||
B_READ_AREA | B_EXECUTE_AREA, comm_area);
|
||||
|
||||
// zero it out
|
||||
memset(comm_ptr, 0, COMMPAGE_SIZE);
|
||||
|
||||
// fill in some of the table
|
||||
comm_ptr[0] = COMMPAGE_SIGNATURE;
|
||||
comm_ptr[1] = COMMPAGE_VERSION;
|
||||
|
||||
// the next slot to allocate space is after the table
|
||||
next_comm_addr = (void *)&comm_ptr[TABLE_ENTRIES];
|
||||
|
||||
// select the optimum syscall mechanism and patch the commpage
|
||||
initialize_commpage_syscall();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
19
src/system/kernel/arch/x86/syscall.S
Normal file
19
src/system/kernel/arch/x86/syscall.S
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2007, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#define FUNCTION(x) .global x; .type x,@function; x
|
||||
#define SYM(x) .global x; x
|
||||
|
||||
.text
|
||||
|
||||
/* user space half of the syscall mechanism, to be copied into the commpage */
|
||||
FUNCTION(_user_syscall_int):
|
||||
int $99
|
||||
ret
|
||||
SYM(_user_syscall_int_end):
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
/*
|
||||
* Copyright 2007, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
/*
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
@ -7,16 +11,18 @@
|
||||
* syscall interface works as such:
|
||||
* eax has syscall #
|
||||
* esp + 4 points to the syscall parameters
|
||||
* branch to the syscall vector in the commpage
|
||||
*/
|
||||
|
||||
#include <os/kernel/arch/x86/commpage.h>
|
||||
|
||||
#define _SYSCALL(name, n) \
|
||||
.globl name; \
|
||||
.type name,@function; \
|
||||
.align 8; \
|
||||
name: \
|
||||
movl $n,%eax; \
|
||||
int $99; \
|
||||
ret
|
||||
jmp *(USER_COMMPAGE_ADDR + COMMPAGE_ENTRY_SYSCALL * 4)
|
||||
|
||||
#define SYSCALL0(name, n) _SYSCALL(name, n)
|
||||
#define SYSCALL1(name, n) _SYSCALL(name, n)
|
||||
@ -35,3 +41,4 @@ name: \
|
||||
#define SYSCALL14(name, n) _SYSCALL(name, n)
|
||||
#define SYSCALL15(name, n) _SYSCALL(name, n)
|
||||
#define SYSCALL16(name, n) _SYSCALL(name, n)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user