9os

Experimental kernel using plan9 ideas for embedded device
git clone git://git.simple-cc.org/9os
Log | Files | Refs | README | LICENSE

ctx.c (2187B)


      1 #include <libk.h>
      2 #include <os9/os9.h>
      3 
      4 #include <string.h>
      5 
      6 #include "arch.h"
      7 #include "sysreg.h"
      8 
      9 static char  regnames[][8] = {
     10 	[X0] = "x0",
     11 	[X1] = "x1",
     12 	[X2] = "x2",
     13 	[X3] = "x3",
     14 	[X4] = "x4",
     15 	[X5] = "x5",
     16 	[X6] = "x6",
     17 	[X7] = "x7",
     18 	[X8] = "x8",
     19 	[X9] = "x9",
     20 	[X10] = "x10",
     21 	[X11] = "x11",
     22 	[X12] = "x12",
     23 	[X13] = "x13",
     24 	[X14] = "x14",
     25 	[X15] = "x15",
     26 	[X16] = "x16",
     27 	[X17] = "x17",
     28 	[X18] = "x18",
     29 	[X19] = "x19",
     30 	[X20] = "x20",
     31 	[X21] = "x21",
     32 	[X22] = "x22",
     33 	[X23] = "x23",
     34 	[X24] = "x24",
     35 	[X25] = "x25",
     36 	[X26] = "x26",
     37 	[X27] = "x27",
     38 	[X28] = "x28",
     39 	[X29] = "x29",
     40 	[ELR] = "elr",
     41 	[X30] = "x30",
     42 	[SPSR] = "spsr",
     43 	[ESR] = "esr",
     44 	[SP_EL0] = "sp_el0",
     45 	[SP_EL1] = "sp_el1",
     46 	[FAR] = "far",
     47 	[TTBR0] = "ttbr0",
     48 	[TTBR1] = "ttbr1",
     49 };
     50 
     51 void
     52 dumpregs(Context *ctx)
     53 {
     54 	int i;
     55 
     56 	for (i = 0; i < NR_REGS; i++) {
     57 		kprint("%s=0x%llx%c", regnames[i], ctx->r[i],
     58 		       (i > 0 && i % 3 == 0) ? '\n' : ' ');
     59 	}
     60 	if (i % 4 != 3)
     61 		kprint("\n");
     62 }
     63 
     64 static void
     65 backtrace(Context *ctx)
     66 {
     67 	void **bp;
     68 
     69 	kprint("backtrace:\n");
     70 	kprint("%0llx\n", ctx->r[X30]);
     71 	for (bp = (void **) ctx->r[X29]; *bp; bp = (void **) *bp)
     72 		kprint("%p\n", bp[1]);
     73 }
     74 
     75 static void
     76 dumpstack(Context *ctx)
     77 {
     78 	long long *sp, i;
     79 
     80 	kprint("stack dump:\n");
     81 	sp = (long long *) ctx->r[SP_EL1];
     82 	for (i = 1; i <= 16; i++)
     83 		kprint("%0llx%c", *sp++, (i % 4 == 0) ? '\n' : ' ');
     84 }
     85 
     86 void
     87 fault(const char *msg, Context *ctx)
     88 {
     89 	static int first = 1;
     90 	Context local;
     91 
     92 	if (first) {
     93 		first = 0;
     94 		kprint("panic: %s\n", msg);
     95 		if (!ctx)
     96 			ctx = getctx(&local);
     97 		dumpregs(ctx);
     98 		backtrace(ctx);
     99 		dumpstack(ctx);
    100 	}
    101 	halt();
    102 }
    103 
    104 void
    105 panic(const char *msg)
    106 {
    107 	fault(msg, NULL);
    108 }
    109 
    110 int
    111 dupctx(Task *tp)
    112 {
    113 	proc->ctx.r[X0] = 1;
    114 	getctx(&tp->ctx);
    115 	tp->ctx.r[X0] = 0;
    116 
    117 	/*
    118 	 * When this function is called tp and proc are different pointers
    119 	 * but when the context of tp is restored and the execution comes
    120 	 * here then tp and proc are the same pointer
    121 	 */
    122 	return proc->ctx.r[X0];
    123 }
    124 
    125 void
    126 ictx(Task *tp, void *fn)
    127 {
    128 	uint64_t *rp;
    129 
    130 	rp = tp->ctx.r;
    131 	memset(rp, 0, sizeof(tp->ctx.r));
    132 
    133 	rp[X30] = (uint64_t) outsync;
    134 	rp[SP_EL1] = tp->kstack.va;
    135 	rp[SPSR] = sysrd(SPSR_EL1);
    136 	rp[ELR] = (uint64_t) fn;
    137 }