summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/cpumgr.C8
-rw-r--r--src/kernel/exception.C4
-rw-r--r--src/kernel/idebug.C89
-rw-r--r--src/kernel/kernel.C2
-rw-r--r--src/kernel/makefile2
-rw-r--r--src/kernel/taskmgr.C12
6 files changed, 108 insertions, 9 deletions
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index 6ec3b9f6d..626ad7f84 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -42,11 +42,14 @@ uint64_t CpuManager::cv_shutdown_status = 0;
Barrier CpuManager::cv_barrier;
bool CpuManager::cv_defrag = false;
size_t CpuManager::cv_cpuCount = 0;
+InteractiveDebug CpuManager::cv_interactive_debug;
CpuManager::CpuManager()
{
for (int i = 0; i < MAXCPUS; i++)
cv_cpus[i] = NULL;
+
+ memset(&cv_interactive_debug, '\0', sizeof(cv_interactive_debug));
}
cpu_t* CpuManager::getCurrentCPU()
@@ -178,6 +181,11 @@ void CpuManager::executePeriodics(cpu_t * i_cpu)
{
if(i_cpu->master)
{
+ if (cv_interactive_debug.isReady())
+ {
+ cv_interactive_debug.startDebugTask();
+ }
+
++(i_cpu->periodic_count);
if(0 == (i_cpu->periodic_count % CPU_PERIODIC_CHECK_MEMORY))
{
diff --git a/src/kernel/exception.C b/src/kernel/exception.C
index cbe97b220..863743f06 100644
--- a/src/kernel/exception.C
+++ b/src/kernel/exception.C
@@ -75,8 +75,8 @@ void kernel_execute_data_storage()
}
if (!handled)
{
- printk("Data Storage exception on %d: %lx, %lx\n",
- t->tid, getDAR(), getDSISR());
+ printk("Data Storage exception on %d: %lx, %lx @ %p\n",
+ t->tid, getDAR(), getDSISR(), t->context.nip);
TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
}
}
diff --git a/src/kernel/idebug.C b/src/kernel/idebug.C
new file mode 100644
index 000000000..673ecb149
--- /dev/null
+++ b/src/kernel/idebug.C
@@ -0,0 +1,89 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/kernel/idebug.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#include <kernel/idebug.H>
+#include <kernel/console.H>
+#include <kernel/cpumgr.H>
+#include <kernel/scheduler.H>
+#include <sys/task.h>
+
+ // Set Ready = 0, Running = 1, Complete = 0.
+static const uint64_t IDEBUG_RUNNING_STATE = 0x0001000000000000ull;
+ // Set Ready = 0, Running = 0, Complete = 1.
+static const uint64_t IDEBUG_COMPLETE_STATE = 0x0000010000000000ull;
+
+void InteractiveDebug::startDebugTask()
+{
+ // Atomically set state to 'running'.
+ // Set Ready = 0, Running = 1, Complete = 0.
+ __sync_lock_test_and_set(&state_value, IDEBUG_RUNNING_STATE);
+
+ // Create userspace task to execute function.
+ task_t* t = TaskManager::createTask(&debugEntryPoint, this, true);
+ CpuManager::getCurrentCPU()->scheduler->addTask(t);
+
+ return;
+}
+
+void InteractiveDebug::debugEntryPoint(void* i_idObject)
+{
+ // Detach task so it is cleaned up properly once it exits.
+ task_detach();
+
+ // Get interactive debug structure from cast of input paramater.
+ InteractiveDebug* interactiveDebug =
+ static_cast<InteractiveDebug*>(i_idObject);
+
+ // Get function pointer from 'entry_point_toc'.
+ typedef uint64_t(*func)(uint64_t,uint64_t,uint64_t,uint64_t,
+ uint64_t,uint64_t,uint64_t,uint64_t);
+ func entry_point =
+ reinterpret_cast<func>(interactiveDebug->entry_point_toc);
+
+ // Call function with parameters.
+ // Due to the PowerABI, parameters get passed in r3-r10 and any
+ // unused parameters are ignored by the called function. You can
+ // therefore treat every function as if it has 8 parameters, even
+ // if it has fewer, and the calling conventions are the same from
+ // an assembly perspective.
+ interactiveDebug->return_value =
+ entry_point(interactiveDebug->parms[0],
+ interactiveDebug->parms[1],
+ interactiveDebug->parms[2],
+ interactiveDebug->parms[3],
+ interactiveDebug->parms[4],
+ interactiveDebug->parms[5],
+ interactiveDebug->parms[6],
+ interactiveDebug->parms[7]);
+
+ // Atomically set state to 'complete'.
+ // This must be proceeded by a sync to ensure all memory operations
+ // and instructions have fully completed prior to setting the complete
+ // state (due to weak consistency).
+ // Set Ready = 0, Running = 0, Complete = 1.
+ __sync_synchronize();
+ __sync_lock_test_and_set(&interactiveDebug->state_value,
+ IDEBUG_COMPLETE_STATE);
+
+ task_end();
+}
+
diff --git a/src/kernel/kernel.C b/src/kernel/kernel.C
index 557a1c81c..cbac9a20f 100644
--- a/src/kernel/kernel.C
+++ b/src/kernel/kernel.C
@@ -117,7 +117,7 @@ void Kernel::cpuBootstrap()
void Kernel::inittaskBootstrap()
{
- task_t * t = TaskManager::createTask(&init_main, NULL);
+ task_t * t = TaskManager::createTask(&init_main, NULL, true);
t->cpu = CpuManager::getCurrentCPU();
TaskManager::setCurrentTask(t);
}
diff --git a/src/kernel/makefile b/src/kernel/makefile
index 2ec3db0d9..05c15115a 100644
--- a/src/kernel/makefile
+++ b/src/kernel/makefile
@@ -26,7 +26,7 @@ OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o
OBJS += syscall.o scheduler.o spinlock.o exception.o vmmmgr.o timemgr.o
OBJS += futexmgr.o ptmgr.o segmentmgr.o devicesegment.o basesegment.o
OBJS += block.o cpuid.o misc.o msghandler.o blockmsghdlr.o stacksegment.o
-OBJS += softpatch_p7.o barrier.o
+OBJS += softpatch_p7.o barrier.o idebug.o
include ${ROOTPATH}/config.mk
diff --git a/src/kernel/taskmgr.C b/src/kernel/taskmgr.C
index ad2aa3af5..b71bd2f25 100644
--- a/src/kernel/taskmgr.C
+++ b/src/kernel/taskmgr.C
@@ -68,9 +68,11 @@ task_t* TaskManager::createIdleTask()
return Singleton<TaskManager>::instance()._createIdleTask();
}
-task_t* TaskManager::createTask(TaskManager::task_fn_t t, void* p)
+task_t* TaskManager::createTask(TaskManager::task_fn_t t, void* p,
+ bool kernelParent)
{
- return Singleton<TaskManager>::instance()._createTask(t, p, true);
+ return Singleton<TaskManager>::instance()._createTask(t, p, true,
+ kernelParent);
}
void TaskManager::endTask(task_t* t, void* retval, int status)
@@ -85,11 +87,11 @@ void TaskManager::waitTask(task_t* t, int64_t tid, int* status, void** retval)
task_t* TaskManager::_createIdleTask()
{
- return this->_createTask(&TaskManager::idleTaskLoop, NULL, false);
+ return this->_createTask(&TaskManager::idleTaskLoop, NULL, false, true);
}
task_t* TaskManager::_createTask(TaskManager::task_fn_t t,
- void* p, bool withStack)
+ void* p, bool withStack, bool kernelParent)
{
task_t* task = new task_t;
memset(task, '\0', sizeof(task_t));
@@ -144,7 +146,7 @@ task_t* TaskManager::_createTask(TaskManager::task_fn_t t,
// Assign parent for tracker instance, add to task tree.
iv_spinlock.lock();
- task_t* parent = getCurrentTask();
+ task_t* parent = kernelParent ? NULL : getCurrentTask();
if (NULL == parent)
{
tracker->parent = NULL;
OpenPOWER on IntegriCloud