diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-05-25 17:11:33 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-06-02 15:13:56 -0500 |
commit | f0e44bc60ca80d5bf875f0836a119e361d84dd44 (patch) | |
tree | d1b7d267a6e292e8c6d10363e7c1df6f7067cb9c /src | |
parent | 83e18669b6c2322c8eb5f8632ac823877d765e0d (diff) | |
download | talos-hostboot-f0e44bc60ca80d5bf875f0836a119e361d84dd44.tar.gz talos-hostboot-f0e44bc60ca80d5bf875f0836a119e361d84dd44.zip |
Add HMER access syscalls (as fastpath).
Change-Id: Icc7494986d19950a18cc9ee53fd5125c86096a72
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/105
Tested-by: Jenkins Server
Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/kernel/ppcconsts.S | 1 | ||||
-rw-r--r-- | src/include/kernel/syscalls.H | 53 | ||||
-rw-r--r-- | src/include/sys/mmio.h | 14 | ||||
-rw-r--r-- | src/kernel/start.S | 42 | ||||
-rw-r--r-- | src/kernel/syscall.C | 6 | ||||
-rw-r--r-- | src/lib/syscall_mmio.C | 10 | ||||
-rw-r--r-- | src/lib/syscall_task.C | 4 |
7 files changed, 115 insertions, 15 deletions
diff --git a/src/include/kernel/ppcconsts.S b/src/include/kernel/ppcconsts.S index ae972f269..38fd5e6e5 100644 --- a/src/include/kernel/ppcconsts.S +++ b/src/include/kernel/ppcconsts.S @@ -102,6 +102,7 @@ .set HDEC,310 .set HSRR0,314 .set HSRR1,315 + .set HMER,336 .set HID0,1008 .set PIR, 1023 diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H index 330db6922..1b87c5019 100644 --- a/src/include/kernel/syscalls.H +++ b/src/include/kernel/syscalls.H @@ -1,36 +1,81 @@ +/** @file syscalls.H + * @brief Defines all the system call IDs to be shared between the kernel and + * the system libc. + */ + #ifndef __KERNEL_SYSCALLS_H #define __KERNEL_SYSCALLS_H namespace Systemcalls { + /** @enum SysCalls + * @brief List of normal system calls and their IDs. + * + * These are passed by userspace code via r3 when the sc instruction is + * executed. The kernel performs a case statement to switch to the + * appropriate system call handler. + */ enum SysCalls { + /** task_yield() */ TASK_YIELD = 0, + /** task_create() */ TASK_START, + /** task_end() */ TASK_END, - TASK_GETTID, - + + /** mutex_create() */ MUTEX_CREATE, + /** mutex_destroy() */ MUTEX_DESTROY, + /** mutex_lock() */ MUTEX_LOCK_CONTESTED, + /** mutex_unlock() */ MUTEX_UNLOCK_CONTESTED, - + + /** msgq_create() */ MSGQ_CREATE, + /** msgq_destroy() */ MSGQ_DESTROY, + /** VFS internal */ MSGQ_REGISTER_ROOT, + /** VFS internal */ MSGQ_RESOLVE_ROOT, - + + /** msg_send() */ MSG_SEND, + /** msg_sendrecv() */ MSG_SENDRECV, + /** msg_respond() */ MSG_RESPOND, + /** msg_wait() */ MSG_WAIT, + /** mmio_map() */ MMIO_MAP, + /** mmio_unmap() */ MMIO_UNMAP, + /** nanosleep() */ TIME_NANOSLEEP, SYSCALL_MAX }; + + /** @enum SysCalls_FastPath + * @brief List of fast-path system calls and their IDs. + * + * @note If any of these change, their handling in start.S must also be + * updated. The ASM code relies on these values. + */ + enum SysCalls_FastPath + { + /** mmio_hmer_read() */ + MMIO_HMER_READ = 0x0800, + /** mmio_hmer_write() */ + MMIO_HMER_WRITE = 0x0801, + + SYSCALL_FASTPATH_MAX + }; }; #endif diff --git a/src/include/sys/mmio.h b/src/include/sys/mmio.h index 6a0e7a02b..eb146da72 100644 --- a/src/include/sys/mmio.h +++ b/src/include/sys/mmio.h @@ -11,6 +11,20 @@ extern "C" void* mmio_map(void* ra, size_t pages); int mmio_unmap(void* ea, size_t pages); +/** @fn mmio_hmer_read() + * @brief Reads the protected HMER register. + */ +uint64_t mmio_hmer_read(); + +/** @fn mmio_hmer_write() + * @brief Writes the protected HMER register. + * + * @param[in] value - The value to write into the HMER. + * + * @returns 0. + */ +int mmio_hmer_write(uint64_t value); + #ifdef __cplusplus } #endif diff --git a/src/kernel/start.S b/src/kernel/start.S index 7eaf1fdf9..ac57926b4 100644 --- a/src/kernel/start.S +++ b/src/kernel/start.S @@ -126,7 +126,24 @@ STD_INTERRUPT(prog_ex, 0x700) UNIMPL_INTERRUPT(fp_unavail, 0x800) STD_INTERRUPT(decrementer, 0x900) UNIMPL_INTERRUPT(hype_decrementer, 0x980) -STD_INTERRUPT(system_call, 0xC00) + +;// System Call Exception Vector +;// +;// This exception vector implements the save/restore for normal system calls +;// that require C++ code for handling but also implements a fast-path for +;// some simple calls, such as reading protected SPRs. +;// +;// Since this is called from userspace as a function call (see __syscall* +;// functions) we only need to honor the ELF ABI calling conventions. That +;// means some registers and condition fields can be considered volatile and +;// modified prior to being saved. +;// +.org _start + 0xC00 +intvect_system_call_fast: + cmpi cr0, r3, 0x0800 + bge cr0, system_call_fast_path +STD_INTERRUPT(system_call, 0xC08) + UNIMPL_INTERRUPT(trace, 0xD00) UNIMPL_INTERRUPT(hype_data_storage, 0xE00) UNIMPL_INTERRUPT(hype_inst_storage, 0xE20) @@ -320,6 +337,29 @@ kernel_dispatch_task: rfid ;// Execute task. + ;// @fn system_call_fast_path + ;// Handle fast path system calls. + ;// 0x800 = HMER read (HMER -> r3). + ;// 0x801 = HMER write (r4 -> HMER). +system_call_fast_path: + ;// Check if this is HMER read (0x800). + ;// Compare was already done in system call path. + bne cr0, 2f + mfspr r3, HMER + b 1f ;// Jump to exit point. + ;// Check if this is HMER write (0x801). +2: + cmpi cr0, r3, 0x801 + bne cr0, 3f + mtspr HMER, r4 + li r3, 0 + b 1f ;// Jump to exit point. + ;// Invalid system call, loop for debug. +3: + b 3b +1: + rfid ;// Return from interrupt. + .section .data .balign 1024 kernel_stack: diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 340250f50..837ed3d21 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -47,7 +47,6 @@ namespace Systemcalls &TaskYield, &TaskStart, &TaskEnd, - &TaskGettid, &MutexCreate, &MutexDestroy, @@ -134,11 +133,6 @@ namespace Systemcalls delete t; } - void TaskGettid(task_t* t) - { - TASK_SETRTN(t, t->tid); - } - void MutexCreate(task_t* t) { UserMutex * m = new UserMutex(); diff --git a/src/lib/syscall_mmio.C b/src/lib/syscall_mmio.C index f2dc8ccf8..30ec5bd37 100644 --- a/src/lib/syscall_mmio.C +++ b/src/lib/syscall_mmio.C @@ -12,3 +12,13 @@ int mmio_unmap(void* ea, size_t pages) { return (int64_t) _syscall2(MMIO_UNMAP, ea, (void*)pages); } + +uint64_t mmio_hmer_read() +{ + return (uint64_t) _syscall0(MMIO_HMER_READ); +} + +int mmio_hmer_write(uint64_t value) +{ + return (int)(int64_t)_syscall1(MMIO_HMER_WRITE, (void*)value); +} diff --git a/src/lib/syscall_task.C b/src/lib/syscall_task.C index fcedcb64b..b133ef2e4 100644 --- a/src/lib/syscall_task.C +++ b/src/lib/syscall_task.C @@ -32,13 +32,9 @@ void task_end() tid_t task_gettid() { - // Even though we have a syscall for GETTID, we also have the task in - // GRP13. - register task_t* task; asm volatile("mr %0, 13" : "=r"(task)); return task->tid; - //return (tid_t)_syscall0(TASK_GETTID); } cpuid_t task_getcpuid() |