summaryrefslogtreecommitdiff
path: root/config/bsd/sparc.c
blob: 4f2215ca0f6ec7f16c36cfdfb8a6a2b067c18f9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
 * coswitch for the SPARC architecture
 */

int
coswitch (int *old_cs, int *new_cs, int first)
{
   asm("ta     0x03");                 /* ST_FLUSH_WINDOWS in trap.h     */
   asm("ld     [%fp+0x44], %o0");      /* load old_cs into %o0           */
   asm("st     %sp,[%o0]");            /* Save user stack pointer        */
   asm("st     %fp,[%o0+0x4]");        /* Save frame pointer             */
   asm("st     %i7,[%o0+0x8]");        /* Save return address            */

   if (first == 0) {                   /* this is the first activation   */
      asm("ld  [%fp+0x48], %o0");      /* load new_cs into %o0           */
      asm("ld  [%o0], %o1");           /* load %o1 from cstate[0]        */

      /* Decrement new stack pointer value before loading it into sp.    */
      /* The top 64 bytes of the stack are reserved for the kernel, to   */
      /* save the 8 local and 8 in registers into, on context switches,  */
      /* interrupts, traps, etc.                                         */

      asm("save  %o1,-96, %sp");       /* load %sp from %o1              */
      new_context(0,0);
      syserr("new_context() returned in coswitch");

   } else {
      asm("ld  [%fp+0x48], %o0");      /* load new_cs into %o0           */
      asm("ld  [%o0+0x4],%fp");        /* Load frame pointer             */
      asm("ld  [%o0+0x8],%i7");        /* Load return address            */
      asm("ld  [%o0],%sp");            /* Load user stack pointer        */
   }
}