gamma_aint.c 2.08 KB
/*
 * Copyright (C) 1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * Copyright (C) 1998 Digital Equipment Corporation
 *
 * This file is part of the SimOS distribution.
 * See LICENSE file for terms of the license.
 *
 */


#include <setjmp.h>
#include <alpha/inst.h>
#include <alpha/pal.h>

#include "simtypes.h"
#include "sim_error.h"
#include "gamma.h"

#include "thread.h"
#include "event.h"
#include "opcodes.h"
#include "globals.h"
#include "alpha_regs.h"
#include "memory.h"
#include "subst.h"
#include "header.h"
#include "mmu.h"
#include "disassembler.h"

/* #define DEBUG_PAL */

static Result  GammaExitThread(AlphaState *P);
extern jmp_buf jmpEnv;

int PALOpcode(AlphaState *P, int func)
{
   if (func==PAL_callsys) {
      Reg oldPC = P->PC;
      Reg newPC;
      SyscallStatus status;
#ifdef DEBUG_PAL
      CPUWarning("PAL opcode at  pc=0x%lx v0=%lx a0=0x%lx \n",
		P->PC,P->reg[REG_V0],P->reg[REG_A0]);
#endif
      status = callsys_f(P->aintThread);
      switch(status) {
      case SYSCALL_NEXT: 
	 newPC = oldPC +4;
	 break;
      case SYSCALL_SAME: 
	 newPC =oldPC;
	 break;
      case SYSCALL_EXIT:
	 return GammaExitThread(P);
      default: 
	 newPC = 0;
	 ASSERT(0);
      }
      P->PC = newPC;
      return SUCCESS;
   }
   ASSERT(0);
   return SUCCESS;
}


static Result  GammaExitThread(AlphaState *P)
{
   int i,j=-1;
   thread_ptr ptr = P->aintThread;
   P->cpuState = cpu_halted;
   ptr->runstate = R_DONE;
   ptr->time = 12; /* random, bogus */
   for(i=0;gammaThreads[i];i++) {
      if (gammaThreads[i]==P) j = i;
   }
   if (i<=1) {
      longjmp(jmpEnv,1);
   }
   ASSERT(j>=0);
   if (j==i-1) {
      gammaThreads[j]= 0;
   } else { 
      gammaThreads[j] = gammaThreads[i-1];
      gammaThreads[i-1] = 0;
   }

   
   return SUCCESS;
}


void GammaNewThread(thread_ptr child)
{
   AlphaState *ch = &child->st;
   int i;

   ch->aintThread = child;
   ch->cpuState = cpu_running;
   for (i=0; gammaThreads[i];i++) {
   }
   gammaThreads[i] = ch;
#ifdef DEBUG_PAL
   CPUWarning("NewThread %d at 0x%lx. thread 0 at %lx \n",
	      child->pid,ch->PC);
#endif
}