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:
Travis Geiselbrecht 2007-02-19 00:32:44 +00:00
parent badc7b674e
commit 1cbf8f4b3c
7 changed files with 143 additions and 2 deletions

View 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

View 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

View File

@ -31,6 +31,8 @@ KernelStaticLibrary libx86 :
apm.cpp
bios.cpp
cpuid.S
commpage.c
syscall.S
generic_vm_physical_page_mapper.cpp
:

View File

@ -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;
}

View 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;
}

View 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):

View File

@ -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)