diff options
| author | Patrick Williams <iawillia@us.ibm.com> | 2010-06-22 16:41:25 -0500 |
|---|---|---|
| committer | Patrick Williams <iawillia@us.ibm.com> | 2010-06-22 16:41:25 -0500 |
| commit | 261aa2b9b790868a16a6cee0f19c73221ddc81d5 (patch) | |
| tree | 324a74523aa6596705ae2021c494e6acd2ddbb89 /src/kernel/exception.C | |
| parent | 02b38895c3af9ce6aae9bc02ef2930fabefff628 (diff) | |
| download | talos-hostboot-261aa2b9b790868a16a6cee0f19c73221ddc81d5.tar.gz talos-hostboot-261aa2b9b790868a16a6cee0f19c73221ddc81d5.zip | |
Program exception handling and emulated instruction for mfsprg3.
Diffstat (limited to 'src/kernel/exception.C')
| -rw-r--r-- | src/kernel/exception.C | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/kernel/exception.C b/src/kernel/exception.C new file mode 100644 index 000000000..98d36c35c --- /dev/null +++ b/src/kernel/exception.C @@ -0,0 +1,58 @@ +#include <kernel/types.h> +#include <kernel/console.H> +#include <kernel/task.H> +#include <kernel/taskmgr.H> +#include <kernel/ppcarch.H> + +namespace Systemcalls { void TaskEnd(task_t*); } +namespace ExceptionHandles +{ + bool HvEmulation(task_t*); +} + +const uint64_t EXCEPTION_SRR1_MASK = 0x00000000783F0000; +const uint64_t EXCEPTION_SRR1_HVEMUL = 0x0000000000080000; + +extern "C" +void kernel_execute_prog_ex() +{ + task_t* t = TaskManager::getCurrentTask(); + uint64_t exception = ppc_getSRR1() & EXCEPTION_SRR1_MASK; + + bool handled = false; + switch(exception) + { + case EXCEPTION_SRR1_HVEMUL: + handled = ExceptionHandles::HvEmulation(t); + break; + } + if (!handled) + { + printk("Program exception, killing task %d\n", t->tid); + Systemcalls::TaskEnd(t); + } +} + +namespace ExceptionHandles +{ + bool HvEmulation(task_t* t) + { + /*printk("NIP = %llx : Inst = %lx\n", + t->context.nip, + (*(uint32_t*)t->context.nip));*/ + + uint32_t instruction = *(uint32_t*)t->context.nip; + + // check for mfsprg3 + if ((instruction & 0xfc1fffff) == 0x7c1342a6) + { + t->context.gprs[(instruction & 0x03E00000) >> 21] = + (uint64_t) t; + t->context.nip = (void*) (((uint64_t)t->context.nip)+4); + return true; + } + + return false; + } + +} |

