cpu_interface.h 5.95 KB
/*
 * Copyright (C) 1996-1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * 
 * This file is part of the SimOS distribution. 
 * See LICENSE file for terms of the license. 
 *
 */

/****************************************************************
 * cpu_interface.h
 * 
 * CPUVec contains the functions that are Mipsy/Mshade specific
 * and that are only called by the Simulator. Therefore it is not in
 * a backdoor and there is no need to play witht the gp in these 
 * functions.
 * 
 * Author: $Author: blythe $
 * Date:   $Date: 2002/05/29 01:09:09 $
 *****************************************************************/

#ifndef CPU_INTERFACE_H
#define CPU_INTERFACE_H

#ifndef _LANGUAGE_ASSEMBLY
#include "annotations.h"
#include "simtypes.h"
#include "syslimits.h"
#include "eventcallback.h"
#include "../../memsystems/memsys.h"

extern CPUType simosCPUType;

/* Used by FaultInject */
typedef enum {
   SIMFAULT_IPARITY = 0,
   SIMFAULT_DPARITY,
   SIMFAULT_ECC,
   SIMFAULT_HALT,
   SIMFAULT_POWERFAIL,
   SIMFAULT_DISABLECPU
} faultTypeEnum;

typedef enum CPUStatus {
  cpu_running,         /* executing instructions */
  cpu_stalled,         /* stalled for a cache miss */
  cpu_stalled_uncached,   /* stalled for a uncached access */
  cpu_halted,          /* halted by a (simulated) hardware failure */
  cpu_bdoor_stalled,   /* Stalled for a backdoor (lock,sync, etc.) operation */
  cpu_libc_blocked,    /* blocked waiting to get into libc */
  cpu_idle,            /* In some idle loop. Unstall on ints and watchpoints */
  cpu_not_booted,       /* This takes the place of the bootprom */
  cpu_blocked          /* SOLO only */
} CPUStatus;

struct CPUVector {
  /* ********************************************************************** *
   * These fields are set by the CPU simulators to reflect current state    * 
   * ********************************************************************** */
   int intrBits[SIM_MAXCPUS]; /* interrupt bits (for all CPU's) */

  /* ********************************************************************** *
   * These fields are set by the CPU simulators to simulate virtual methods * 
   * ********************************************************************** */
   CPUStatus (*CPUstatus) (int cpuNum);
   SimTime (*CycleCount)  (int cpuNum);
   SimTime (*InstrCount)  (int cpuNum);

   /* CPU Interface to gdb and tcl */
   void (*Handle_Debug_Signal)(int cpuid, int sigusr);  

   Result (*GetRegister)(int cpunum, int regnum, Reg *val);
   Result (*PutRegister)(int cpunum, int regnum, Reg val);

   void   (*ClearLockFlag)(int cpunum);
   bool   (*GetLockFlag)(int cpunum);
   PA     (*GetLockAddr)(int cpunum);

   Result (*GetMemory)(int cpunum, VA vAddr, uint nbytes, char *buf);
   Result (*PutMemory)(int cpunum, VA vAddr, uint nbytes, char *buf);
   Result (*TranslateVirtualNoSE)(int cpunum,VA vAddr, PA *pAddr);

   bool singleEventQueue;  
    
   void (*LaunchSlaveCPU)(int cpuNum); /* MIPS polls, Alpha uses this call */
   
   void (*Send_Interrupt) (int cpuNum, IEC ccode, SimTime delay); 

   void (*Unstall) (int cpuNum);

   Result (*UncachedPIO)(int cpuNum, PA pA, int isRead, int size, void *data);

   void (*ReissueUncachedOp)(int cpuNum);


   /* Post the specified interrupt on the specified CPU after
    * the specified delay in time.
    */
   void (*Deliver_SIPS) (int cpuNum, int chan, SimTime delay);

   /* Simulates the SIPS propagation latency. In Mipsy, the SIPS is
    * put into the receiver's buffer by send_sips, but the buffer is
    * marked as full and an interrupt is delivered only when this
    * routine is called. 
    */

   /* Fault injection support for the CPU.  */
   void (*FaultInject)(int cpuNum, faultTypeEnum faultType);

   /* Reset a cpu -- should put PC back into the promslave loop
    * and clear all cached state about interrupts, etc.
    */
   int (*ResetCPU)(int cpuNum);

  /* Perform any initialization that needs to occur before the checkpoint restore. */
   void (*EarlyInit)(void);

   /* Dump stats before selector change */
   void (*SelectorChange) (int cpuNum);

   void (*DoCheckpoint)(int cpuNum);

   /* Procexit Support - Do something to registers/memory of current
      process that will cause it to exit */ 
   void (*ProcMakeProcExit)( int cpuNum );

   void (*ExitSimulator)( CPUType toSim );

   /* Current Functions */
   int (*CurrentCpuNum)(void);
   VA  (*CurrentPC)(int cpuNum);  
   Inst (*CurrentInstruction)(int cpuNum);

   void (*TakeBusError)(int cpuNum, bool isIRef, VA);

   /* function to call if you change the SYSAD intr bits directly
    * (rather than calling SendIntr -- eg. if flashlite is providing
    * IEC functionality)
    */
   void (*IntrBitsChanged)( int cpuNum );

   /* Migration-replication implementation. */
   void (*MigRepStart)( int cpuNum );
   void (*MigRepEnd)( int cpuNum );

   void (*InstallMemAnnotation)(VA vAddr);

   /* function to call if you change the firewall permissions granted
    * to a set of cpus.  CPU model should set this field to zero if
    * it isn't caching anything so doesn't need the callback.
    *
    * grant = 1  newly granting write permission, = 0 retracting
    * cpumask bit i set to 1 if that cpu's permission has changed
    */
   void (*FirewallChange)(PA pAddr, uint grant, uint64 cpumask);
   uint  (*CheckFirewall)(int cpuNum, PA pAddr);

   /* This function is called with a list of k0 pages that are being */
   /* filled by  DMA */

   /* Embra needs to see this to determine if  the translation cache */
   /* needs to be flushed */ 
   void (*DMAInval)(int machine, PA* k0list);

   /* Function that maps the PA on the target machine to the virtual address 
    * where this value can be found on the host machine. */
   char *(*PAToHostAddr)(int cpuNum, PA pAddr, VA vAddr);
 
   /* keep track of whether clock has been started and the clock interval */
   bool clockStarted[SIM_MAXCPUS];
   int  clockInterval[SIM_MAXCPUS];
   bool useMemRef;
};

extern struct CPUVector CPUVec;

#endif /* _LANGUAGE_ASSEMBLY*/
#endif /*CPU_INTERFACE_H */