summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-05-25 17:11:33 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-06-02 15:13:56 -0500
commitf0e44bc60ca80d5bf875f0836a119e361d84dd44 (patch)
treed1b7d267a6e292e8c6d10363e7c1df6f7067cb9c /src
parent83e18669b6c2322c8eb5f8632ac823877d765e0d (diff)
downloadtalos-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.S1
-rw-r--r--src/include/kernel/syscalls.H53
-rw-r--r--src/include/sys/mmio.h14
-rw-r--r--src/kernel/start.S42
-rw-r--r--src/kernel/syscall.C6
-rw-r--r--src/lib/syscall_mmio.C10
-rw-r--r--src/lib/syscall_task.C4
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()
OpenPOWER on IntegriCloud