⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simos_interface.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * 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.  * *//***************************************************************** * simos_interface.c - SimOS interface to the HP disk simulator.  * Always runs on thread 0.  *  * $Author: bosch $ * $Date: 1998/02/10 00:36:50 $ *****************************************************************/#include "sim.h"#include "simtypes.h"#include "simos_interface.h"#include "diskdevice.h"#include "diskdevices.h"#include "modularize.h"#include "queue.h"#include "eventcallback.h"#include "hd.h"#include "cpu_interface.h"#include "heap.h"#include "simutil.h"#include "sim_error.h"#include "machine_params.h"Heap heap;			/* the event heap */double diskTICSperMSEC;typedef struct DiskModelCallback{     EventCallbackHdr hdr; /* Event header of the callback */    int diskNum;    int sector;    int nsectors;     int iswrite;    dmaRoutine_t dmaRoutine;    void *dmaArg;    doneRoutine_t doneRoutine;    int doneArg;} DiskModelCallback;DiskModelCallback *diskModelCallback;EventCallbackHdr *diskModelEhdr;#define BQSIZE    15		/* size of bus queue */ /* * DiskModelInit - Initialize the HP disk model. We allow the user to  *                 specify the MAX number of disks being models and  *                 how the time of the disk model should be scaled.  *                 A scaling factor of 1.0 gives realistic timings.  */voidDiskModelInit(int maxNumDisks, double scaling){    int diskNum;    int *busOwner;    NCQUEUE *busWaitq;    if (scaling == 0) {       CPUError("HD: Can't run HP disk at scaling of 0... use fixed model.\n");    }    /*  diskTICSperMSEC = (scaling*1000.0*1000.0)/(double)simConfigNsecPerInstr; */    SIMASSERT(  CPU_CLOCK );    diskTICSperMSEC = (scaling * 1000.0 * CPU_CLOCK) ;        InitTime();		            /* initialize the global clock */    busOwner = (int *) MALLOC(sizeof(int),"busOwner");    *busOwner = BUS_FREE;    busWaitq = MakeQueue_noncyc(BQSIZE, "bus queue");    for (diskNum = 0; diskNum < maxNumDisks; diskNum++) {       DiskDeviceInit(diskNum, diskNum, busOwner, busWaitq, NULL);    }           /* Currently we model each disk as having its own SCSI bus.  */    diskModelEhdr = (EventCallbackHdr *)        ZMALLOC(sizeof(EventCallbackHdr),"DiskModelEHdr");        diskModelCallback = (DiskModelCallback *)        ZMALLOC(sizeof(DiskModelCallback)*SIM_MAX_DISKS, "DiskModelCallback");    ASSERT( diskModelCallback );} /* * DiskModelRequest - Start the modeling of a DISK request. We allow the user  *                    to provide routines to handle the data as it comes over  *                    the SCSI bus (dmaRoutine) and the compleition response *                    (doneroutine). * Because we do not want to have to deal with shared memory in MP embra,  * we run all of the disk model requests on CPU 0. The DMA module is shared  * memory mapped. The final callback interrupts the CPU that requested the  * transfer in the first place  */static void DiskModelStartCallback(int cpuNum,EventCallbackHdr *hdr,void *arg){    TICS begintime = CPUVec.CycleCount(0);    DiskModelCallback *cback = (DiskModelCallback *)hdr;    /*     * Advance the simulator's time to the current time and launch the request.      */    WaitTime(begintime);      DiskDeviceTransferStart(cback->diskNum,                             cback->sector,                             cback->nsectors,                             cback->iswrite,                             cback->dmaRoutine,                                cback->dmaArg,                             cback->doneRoutine,                             cback->doneArg);    }voidDiskModelRequest(int machine, int diskNum, int sector, int nsectors, 		 int iswrite,  dmaRoutine_t dmaRoutine,                 doneRoutine_t doneRoutine, int doneArg){    DiskModelCallback *cback = diskModelCallback+diskNum;    ASSERT( diskModelCallback );    /* get all of the parameter in the callback. Have it handled by CPU 0       of the machine */    cback->diskNum = diskNum;    cback->sector = sector;    cback->nsectors = nsectors;    cback->iswrite = iswrite;    cback->dmaRoutine = dmaRoutine;    cback->doneRoutine = doneRoutine;    cback->doneArg = doneArg;    /* pass over message to CPU 0 of the machine */    EventDoCallback(FIRST_CPU(machine), DiskModelStartCallback,                    (EventCallbackHdr *)cback,0,0);}/* * The following code and data interfaces the event callback mechanism of  * the disk model with the simos Eventcallback mod. This is done by  * recording a EventCallback that corresponds to the ROOT of the callback * Heap maintained by the disk simulator.  */static void RecordCallback(int cpuNum,EventCallbackHdr *ptr, void *arg);static TICS lastregtime;      /* Time of registered callback */voidUpdateEventCallback(TICS tics){       TICS regtime = tics+1;      if (!EventCallbackActive(diskModelEhdr)) { 	  /* If we don't have a callback registers - set one. */	  SimTime time = CPUVec.CycleCount(0);          if (time >= regtime) {             /* This can happen in Embra because the callbacks can be delayed. */             regtime = time+1;          }          EventDoCallback(FIRST_CPU(M_FROM_CPU(diskModelEhdr->cpuNum)),                          RecordCallback,diskModelEhdr, (void *) 0,                          regtime - time);	  lastregtime = regtime;      } else {	  SimTime  time = CPUVec.CycleCount(0);          if (time >= regtime) {             /* This can happen in Embra because the callbacks can be delayed. */             regtime = time+1;          }          if (regtime < lastregtime) {             /* If we have one register's too far in the future - Update it. */             EventCallbackUpdate(diskModelEhdr,regtime);             lastregtime = regtime;          } else {             /* Update wasn't to the root of the heap */          }      }}static voidRecordCallback(int cpuNum,EventCallbackHdr *ptr, void *arg){    HeapKey Hpkey;    HeapData Hpdat;    TICS current_time = CPUVec.CycleCount(0);    /*     * Update the disk's simulated time to the current time  and      * re-register the top of the heap if needed.      */    WaitTime(current_time);    if (TopHeap(heap, &Hpdat, &Hpkey) != FALSE) {       UpdateEventCallback(Hpkey);    }}voidAdvanceTime(void){    TICS begintime = CPUVec.CycleCount(0);    WaitTime(begintime);  /* Update simulators time */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -