Пример #1
0
/*-------------------------------------------------------------------*/
CREG ARCH_DEP(trace_bsg) (U32 alet, VADR ia, REGS *regs)
{
RADR raddr;
RADR ag;
int  size;

#if defined(FEATURE_ESAME)
    if(regs->psw.amode64)
    {
        TRACE_F2_BSG *tte;
        size = sizeof(TRACE_F2_BSG);
        raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
        tte = (void*)(regs->mainstor + raddr);
        tte->format = TRACE_F2_BSG_FMT;
        tte->alet[0] = (alet >> 16) & 0xFF; 
        tte->alet[1] = (alet >> 8) & 0xFF; 
        tte->alet[2] = alet & 0xFF; 
        STORE_DW(tte->newia,ia);
    }
Пример #2
0
/*-------------------------------------------------------------------*/
CREG ARCH_DEP(trace_br) (int amode, VADR ia, REGS *regs)
{
RADR raddr;
RADR ag;
int  size;

#if defined(FEATURE_ESAME)
    if(amode && ia > 0xFFFFFFFFULL)
    {
        TRACE_F3_BR *tte;
        size = sizeof(TRACE_F3_BR);
        raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
        tte = (void*)(regs->mainstor + raddr);
        tte->format = TRACE_F3_BR_FMT;
        tte->fmt2 = TRACE_F3_BR_FM2;
        STORE_HW(tte->resv,0);
        STORE_DW(tte->newia64,ia);
    }
    else
#endif /*defined(FEATURE_ESAME)*/
    if(amode)
    {
        TRACE_F2_BR *tte;
        size = sizeof(TRACE_F2_BR);
        raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
        tte = (void*)(regs->mainstor + raddr);
        STORE_FW(tte->newia31,ia | 0x80000000);
    }
    else
    {
        TRACE_F1_BR *tte;
        size = sizeof(TRACE_F1_BR);
        raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
        tte = (void*)(regs->mainstor + raddr);
        STORE_FW(tte->newia24,ia & 0x00FFFFFF);
    }
    
    return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
    
} /* end function ARCH_DEP(trace_br) */
Пример #3
0
static int ARCH_DEP(scedio_iov)(SCCB_SCEDIOV_BK *scediov_bk)
{
S64     seek;
S64     length;
S64     totread, totwrite;
U64     sto;
char    fname[MAX_PATH];

    switch(scediov_bk->type) {

    case SCCB_SCEDIOV_TYPE_INIT:
        return TRUE;
        break;


    case SCCB_SCEDIOV_TYPE_READ:
        /* Ensure file access is allowed and within specified directory */
        if(!check_sce_filepath((char*)scediov_bk->filename,fname))
        {
            if(errno != ENOENT)
                WRMSG (HHC00605, "E", fname, strerror(errno));
            return FALSE;
        }
        FETCH_DW(sto,scediov_bk->sto);
        FETCH_DW(seek,scediov_bk->seek);
        FETCH_DW(length,scediov_bk->length);

        totread = ARCH_DEP(read_file)(fname, sto, seek, length);

        if(totread > 0)
        {
            STORE_DW(scediov_bk->length,totread);

            if(totread == length)
                STORE_DW(scediov_bk->ncomp,0);
            else
                STORE_DW(scediov_bk->ncomp,seek+totread);

            return TRUE;
        }
        else
            return FALSE;

        break;


    case SCCB_SCEDIOV_TYPE_CREATE:
    case SCCB_SCEDIOV_TYPE_APPEND:
        /* Ensure file access is allowed and within specified directory */
        if(!check_sce_filepath((char*)scediov_bk->filename,fname))
        {
            if(errno != ENOENT)
                WRMSG (HHC00605, "E", fname, strerror(errno));

            /* A file not found error may be expected for a create request */
            if(!(errno == ENOENT && scediov_bk->type == SCCB_SCEDIOV_TYPE_CREATE))
                return FALSE;
        }
        FETCH_DW(sto,scediov_bk->sto);
        FETCH_DW(length,scediov_bk->length);

        totwrite = ARCH_DEP(write_file)(fname,
          ((scediov_bk->type == SCCB_SCEDIOV_TYPE_CREATE) ? (O_CREAT|O_TRUNC) : O_APPEND), sto, length);

        if(totwrite >= 0)
        {
            STORE_DW(scediov_bk->ncomp,totwrite);
            return TRUE;
        }
        else
            return FALSE;
        break;


    default:
        PTT(PTT_CL_ERR,"*SERVC",(U32)scediov_bk->type,(U32)scediov_bk->flag1,scediov_bk->flag2);
        return FALSE;

    }
}
Пример #4
0
/*-------------------------------------------------------------------*/
void ARCH_DEP(diag204_call) (int r1, int r2, REGS *regs)
{
DIAG204_HDR       *hdrinfo;            /* Header                     */
DIAG204_PART      *partinfo;           /* Partition info             */
DIAG204_PART_CPU  *cpuinfo;            /* CPU info                   */
#if defined(FEATURE_EXTENDED_DIAG204)
DIAG204_X_HDR      *hdrxinfo;          /* Header                     */
DIAG204_X_PART     *partxinfo;         /* Partition info             */
DIAG204_X_PART_CPU *cpuxinfo;          /* CPU info                   */
U64               tdis;       
#endif /*defined(FEATURE_EXTENDED_DIAG204)*/
RADR              abs;                 /* abs addr of data area      */
U64               dreg;                /* work doubleword            */
int               i;                   /* loop counter               */
struct rusage     usage;               /* RMF type data              */
static U64        diag204tod;          /* last diag204 tod           */
#if defined(FEATURE_PHYSICAL_DIAG204)
static BYTE       physical[8] =
              {0xD7,0xC8,0xE8,0xE2,0xC9,0xC3,0xC1,0xD3}; /* PHYSICAL */
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/

    /* Test DIAG204 command word */
    switch (regs->GR_L(r2)) {

    case 0x04:

        abs = APPLY_PREFIXING (GR_A(r1,regs), regs->PX);

        /* Program check if RMF data is not on a page boundary */
        if ( (abs & PAGEFRAME_BYTEMASK) != 0x000)
            ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);

        /* Program check if RMF data area is outside main storage */
        if ( abs > regs->mainlim )
            ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);

        /* Point to DIAG 204 data area */
        hdrinfo = (DIAG204_HDR*)(regs->mainstor + abs);

        /* Mark page referenced */
        STORAGE_KEY(abs, regs) |= STORKEY_REF | STORKEY_CHANGE;

        /* save last diag204 tod */
        dreg = diag204tod;

        /* Retrieve the TOD clock value and shift out the epoch */
        diag204tod = tod_clock(regs) << 8;

        memset(hdrinfo, 0, sizeof(DIAG204_HDR));
        hdrinfo->numpart = 1;
#if defined(FEATURE_PHYSICAL_DIAG204)
        hdrinfo->flags = DIAG204_PHYSICAL_PRESENT;
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/
        STORE_HW(hdrinfo->physcpu,sysblk.cpus);
        STORE_HW(hdrinfo->offown,sizeof(DIAG204_HDR));
        STORE_DW(hdrinfo->diagstck,dreg);

        /* hercules partition */
        partinfo = (DIAG204_PART*)(hdrinfo + 1);
        memset(partinfo, 0, sizeof(DIAG204_PART));
        partinfo->partnum = 1; /* Hercules partition */
        partinfo->virtcpu = sysblk.cpus;
        get_lparname(partinfo->partname);

        /* hercules cpu's */
        getrusage(RUSAGE_SELF,&usage);
        cpuinfo = (DIAG204_PART_CPU*)(partinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuinfo, 0, sizeof(DIAG204_PART_CPU));
              STORE_HW(cpuinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuinfo->index=sysblk.ptyp[i];
              STORE_HW(cpuinfo->weight,100);
              dreg = (U64)(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1000000;
              dreg = (dreg + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)) / sysblk.cpus;
              dreg <<= 12;
              STORE_DW(cpuinfo->totdispatch,dreg);

              dreg = (U64)(usage.ru_utime.tv_sec)* 1000000;
              dreg = (dreg + (usage.ru_utime.tv_usec)) / sysblk.cpus;
              dreg <<= 12;
              STORE_DW(cpuinfo->effdispatch,dreg);

              cpuinfo += 1;
          }

#if defined(FEATURE_PHYSICAL_DIAG204)
        /* lpar management */
        getrusage(RUSAGE_CHILDREN,&usage);
        partinfo = (DIAG204_PART*)cpuinfo;
        memset(partinfo, 0, sizeof(DIAG204_PART));
        partinfo->partnum = 0; /* Physical machine */
        partinfo->virtcpu = sysblk.cpus;
        memcpy(partinfo->partname,physical,sizeof(physical));

        /* report all emulated physical cpu's */
        getrusage(RUSAGE_SELF,&usage);
        cpuinfo = (DIAG204_PART_CPU*)(partinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuinfo, 0, sizeof(DIAG204_PART_CPU));
              STORE_HW(cpuinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuinfo->index = sysblk.ptyp[i];
              STORE_HW(cpuinfo->weight,100);

              dreg = (U64)(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1000000;
              dreg = (dreg + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)) / sysblk.cpus;
              dreg <<= 12;
              STORE_DW(cpuinfo->totdispatch,dreg);

              dreg = (U64)(usage.ru_utime.tv_sec) * 1000000;
              dreg = (dreg + (usage.ru_utime.tv_usec)) / sysblk.cpus;
              dreg <<= 12;
              STORE_DW(cpuinfo->effdispatch,dreg);

              cpuinfo += 1;
          }
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/

        regs->GR_L(r2) = 0;

        break;

#if defined(FEATURE_EXTENDED_DIAG204)
    /* Extended subcode 5 returns the size of the data areas provided by extended subcodes 6 and 7 */
    case 0x00010005:
        i = sizeof(DIAG204_X_HDR) + ((sizeof(DIAG204_X_PART) + (sysblk.maxcpu * sizeof(DIAG204_X_PART_CPU))) * 2);
        regs->GR_L(r2+1) = (i + PAGEFRAME_BYTEMASK) / PAGEFRAME_PAGESIZE;
        regs->GR_L(r2) = 0;

        break;

    /* Provide extended information */
    case 0x00010006:
        /* We fall through as we do not have any secondary cpus (that we know of) */

    /* Provide extended information, including information about secondary CPUs */
    case 0x00010007:
        /* Program check if RMF data is not on a page boundary */
        if ( (regs->GR_L(r1) & PAGEFRAME_BYTEMASK) != 0x000)
            ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);

        /* Obtain absolute address of main storage block,
           check protection, and set reference and change bits */
        hdrxinfo = (DIAG204_X_HDR*)MADDR (GR_A(r1,regs), r1, regs, ACCTYPE_WRITE, regs->psw.pkey);

        /* save last diag204 tod */
        dreg = diag204tod;

        /* Retrieve the TOD clock value and shift out the epoch */
        diag204tod = tod_clock(regs) << 8;

        memset(hdrxinfo, 0, sizeof(DIAG204_X_HDR));
        hdrxinfo->numpart = 1;
#if defined(FEATURE_PHYSICAL_DIAG204)
        hdrxinfo->flags = DIAG204_X_PHYSICAL_PRESENT;
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/
        STORE_HW(hdrxinfo->physcpu,sysblk.cpus);
        STORE_HW(hdrxinfo->offown,sizeof(DIAG204_X_HDR));
        STORE_DW(hdrxinfo->diagstck1,(dreg >> 8));
        STORE_DW(hdrxinfo->diagstck2,( 0x0000000001000000ULL | (regs->cpuad << 16) | regs->todpr));

        /* hercules partition */
        partxinfo = (DIAG204_X_PART*)(hdrxinfo + 1);
        memset(partxinfo, 0, sizeof(DIAG204_PART));
        partxinfo->partnum = 1; /* Hercules partition */
        partxinfo->virtcpu = sysblk.cpus;
        get_lparname(partxinfo->partname);
        get_sysname(partxinfo->cpcname);
        get_systype(partxinfo->osname);
        STORE_DW(partxinfo->cssize,sysblk.mainsize);
        STORE_DW(partxinfo->essize,sysblk.xpndsize);
        get_sysplex(partxinfo->gr_name);

        /* hercules cpu's */
        getrusage(RUSAGE_SELF,&usage);
        cpuxinfo = (DIAG204_X_PART_CPU*)(partxinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuxinfo, 0, sizeof(DIAG204_X_PART_CPU));
              STORE_HW(cpuxinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuxinfo->index = sysblk.ptyp[i];
              STORE_HW(cpuxinfo->weight,100);
              
              tdis = (U64)(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1000000;
              tdis = (tdis + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)) / sysblk.cpus;
              tdis <<= 12;
              STORE_DW(cpuxinfo->totdispatch,tdis);

              dreg = (U64)(usage.ru_utime.tv_sec)* 1000000;
              dreg = (dreg + (usage.ru_utime.tv_usec)) / sysblk.cpus;
              dreg <<= 12;
              STORE_DW(cpuxinfo->effdispatch,dreg);

              STORE_HW(cpuxinfo->minweight,1000);
              STORE_HW(cpuxinfo->curweight,1000);
              STORE_HW(cpuxinfo->maxweight,1000);

              STORE_DW(cpuxinfo->onlinetime, diag204tod - sysblk.todstart);
              STORE_DW(cpuxinfo->waittime, (diag204tod - sysblk.todstart) - tdis);

              STORE_HW(cpuxinfo->pmaweight,1000);
              STORE_HW(cpuxinfo->polarweight,1000);

              cpuxinfo += 1;
          }


#if defined(FEATURE_PHYSICAL_DIAG204)
        /* lpar management */
        partxinfo = (DIAG204_X_PART*)cpuxinfo;
        memset(partxinfo, 0, sizeof(DIAG204_X_PART));
        partxinfo->partnum = 0; /* Physical machine */
        partxinfo->virtcpu = sysblk.cpus;
        memcpy(partxinfo->partname,physical,sizeof(physical));

        /* report all emulated physical cpu's */
        getrusage(RUSAGE_CHILDREN,&usage);
        cpuxinfo = (DIAG204_PART_CPU*)(partinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuxinfo, 0, sizeof(DIAG204_X_PART_CPU));
              STORE_HW(cpuxinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuxinfo->index = sysblk.ptyp[i];
              STORE_HW(cpuxinfo->weight,100);
              
              tdis = (U64)(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1000000;
              tdis = (tdis + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)) / sysblk.cpus;
              tdis <<= 12;
              STORE_DW(cpuxinfo->totdispatch,tdis);

              dreg = (U64)(usage.ru_utime.tv_sec)* 1000000;
              dreg = (dreg + (usage.ru_utime.tv_usec)) / sysblk.cpus;
              dreg <<= 12;
              STORE_DW(cpuxinfo->effdispatch,dreg);

              STORE_HW(cpuxinfo->minweight,1000);
              STORE_HW(cpuxinfo->curweight,1000);
              STORE_HW(cpuxinfo->maxweight,1000);

              STORE_DW(cpuxinfo->onlinetime, diag204tod - sysblk.todstart);
              STORE_DW(cpuxinfo->waittime, (diag204tod - sysblk.todstart) - tdis);

              STORE_HW(cpuxinfo->pmaweight,1000);
              STORE_HW(cpuxinfo->polarweight,1000);

              cpuxinfo += 1;
          }
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/

        regs->GR_L(r2) = 0;

        break;
#endif /*defined(FEATURE_EXTENDED_DIAG204)*/

    default:
        PTT(PTT_CL_ERR,"*DIAG204",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
        regs->GR_L(r2) = 4;

    } /*switch(regs->GR_L(r2))*/

} /* end function diag204_call */
Пример #5
0
/*-------------------------------------------------------------------*/
void ARCH_DEP(diag204_call) (int r1, int r2, REGS *regs)
{
DIAG204_HDR       *hdrinfo;            /* Header                     */
DIAG204_PART      *partinfo;           /* Partition info             */
DIAG204_PART_CPU  *cpuinfo;            /* CPU info                   */
#if defined(FEATURE_EXTENDED_DIAG204)
DIAG204_X_HDR      *hdrxinfo;          /* Header                     */
DIAG204_X_PART     *partxinfo;         /* Partition info             */
DIAG204_X_PART_CPU *cpuxinfo;          /* CPU info                   */
#endif /*defined(FEATURE_EXTENDED_DIAG204)*/
RADR              abs;                 /* abs addr of data area      */
int               i;                   /* loop counter               */
struct rusage     usage;               /* RMF type data              */
ETOD              ETOD;                /* Extended TOD clock         */
U64               uCPU[MAX_CPU_ENGINES];    /* User CPU time    (us) */
U64               tCPU[MAX_CPU_ENGINES];    /* Total CPU time   (us) */

#if defined(FEATURE_PHYSICAL_DIAG204)
static BYTE       physical[8] =
              {0xD7,0xC8,0xE8,0xE2,0xC9,0xC3,0xC1,0xD3}; /* PHYSICAL */
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/

#if defined(FEATURE_EXTENDED_DIAG204)
U64               oCPU[MAX_CPU_ENGINES];    /* Online CPU time  (us) */
U64               wCPU[MAX_CPU_ENGINES];    /* Wait CPU time    (us) */
#endif /*defined(FEATURE_EXTENDED_DIAG204)*/

    /* Test DIAG204 command word */
    switch (regs->GR_L(r2)) {

    case 0x04:

        abs = APPLY_PREFIXING (GR_A(r1,regs), regs->PX);

        /* Program check if RMF data is not on a page boundary */
        if ( (abs & PAGEFRAME_BYTEMASK) != 0x000)
            ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);

        /* Program check if RMF data area is outside main storage */
        if ( abs > regs->mainlim )
            ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);

        /* Point to DIAG 204 data area */
        hdrinfo = (DIAG204_HDR*)(regs->mainstor + abs);

        /* Mark page referenced */
        STORAGE_KEY(abs, regs) |= STORKEY_REF | STORKEY_CHANGE;

        /* Retrieve the TOD clock value */
        etod_clock(regs, &ETOD, ETOD_extended);

        /* Get processor time(s) and leave out non-CPU processes and
         * threads
         */
        for(i = 0; i < sysblk.maxcpu; ++i)
        {
            if (IS_CPU_ONLINE(i))
            {
                /* Get CPU times in microseconds */
                getrusage((int)sysblk.cputid[i], &usage);
                uCPU[i] = timeval2us(&usage.ru_utime);
                tCPU[i] = uCPU[i] + timeval2us(&usage.ru_stime);
            }
        }

        memset(hdrinfo, 0, sizeof(DIAG204_HDR));
        hdrinfo->numpart = 1;
#if defined(FEATURE_PHYSICAL_DIAG204)
        hdrinfo->flags = DIAG204_PHYSICAL_PRESENT;
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/
        STORE_HW(hdrinfo->physcpu,sysblk.cpus);
        STORE_HW(hdrinfo->offown,sizeof(DIAG204_HDR));
        STORE_DW(hdrinfo->diagstck,ETOD2tod(ETOD));

        /* hercules partition */
        partinfo = (DIAG204_PART*)(hdrinfo + 1);
        memset(partinfo, 0, sizeof(DIAG204_PART));
        partinfo->partnum = sysblk.lparnum;     /* Hercules partition */
        partinfo->virtcpu = sysblk.cpus;
        get_lparname(partinfo->partname);

        /* hercules cpu's */
        cpuinfo = (DIAG204_PART_CPU*)(partinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuinfo, 0, sizeof(DIAG204_PART_CPU));
              STORE_HW(cpuinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuinfo->index=sysblk.ptyp[i];
              STORE_HW(cpuinfo->weight,100);
              STORE_DW(cpuinfo->totdispatch,tCPU[i]);
              STORE_DW(cpuinfo->effdispatch, uCPU[i]);
              cpuinfo += 1;
          }

#if defined(FEATURE_PHYSICAL_DIAG204)
        /* LPAR management */
        /* FIXME: This section should report on the real CPUs, appearing
         *        and transformed for reporting purposes. This should
         *        also be properly reflected in STSI information.
         */
        partinfo = (DIAG204_PART*)cpuinfo;
        memset(partinfo, 0, sizeof(DIAG204_PART));
        partinfo->partnum = 0; /* Physical machine */
        partinfo->virtcpu = sysblk.cpus;
        memcpy(partinfo->partname,physical,sizeof(physical));

        /* report all emulated physical cpu's */
        cpuinfo = (DIAG204_PART_CPU*)(partinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuinfo, 0, sizeof(DIAG204_PART_CPU));
              STORE_HW(cpuinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuinfo->index = sysblk.ptyp[i];
              STORE_HW(cpuinfo->weight,100);
              STORE_DW(cpuinfo->totdispatch, tCPU[i]);
              STORE_DW(cpuinfo->effdispatch, uCPU[i]);
              cpuinfo += 1;
          }
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/

        regs->GR_L(r2) = 0;

        break;

#if defined(FEATURE_EXTENDED_DIAG204)
    /* Extended subcode 5 returns the size of the data areas provided by extended subcodes 6 and 7 */
    case 0x00010005:
        i = sizeof(DIAG204_X_HDR) + ((sizeof(DIAG204_X_PART) + (sysblk.maxcpu * sizeof(DIAG204_X_PART_CPU))) * 2);
        regs->GR_L(r2+1) = (i + PAGEFRAME_BYTEMASK) / PAGEFRAME_PAGESIZE;
        regs->GR_L(r2) = 0;

        break;

    /* Provide extended information */
    case 0x00010006:
        /* We fall through as we do not have any secondary cpus (that we know of) */

    /* Provide extended information, including information about secondary CPUs */
    case 0x00010007:
        /* Program check if RMF data is not on a page boundary */
        if ( (regs->GR_L(r1) & PAGEFRAME_BYTEMASK) != 0x000)
            ARCH_DEP(program_interrupt) (regs, PGM_SPECIFICATION_EXCEPTION);

        /* Obtain absolute address of main storage block,
           check protection, and set reference and change bits */
        hdrxinfo = (DIAG204_X_HDR*)MADDR (GR_A(r1,regs), r1, regs, ACCTYPE_WRITE, regs->psw.pkey);

        /* Retrieve the TOD clock value */
        etod_clock(regs, &ETOD, ETOD_extended);

        /* Get processor time(s) and leave out non-CPU processes and
         * threads
         */
        for(i = 0; i < sysblk.maxcpu; ++i)
        {
            if (IS_CPU_ONLINE(i))
            {
                /* Get CPU times in microseconds */
                getrusage((int)sysblk.cputid[i], &usage);
                oCPU[i] = etod2us(ETOD.high - regs->tod_epoch - sysblk.cpucreateTOD[i]);
                uCPU[i] = timeval2us(&usage.ru_utime);
                tCPU[i] = uCPU[i] + timeval2us(&usage.ru_stime);
                wCPU[i] = tCPU[i] - uCPU[i];
            }
        }

        memset(hdrxinfo, 0, sizeof(DIAG204_X_HDR));
        hdrxinfo->numpart = 1;
#if defined(FEATURE_PHYSICAL_DIAG204)
        hdrxinfo->flags = DIAG204_X_PHYSICAL_PRESENT;
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/
        STORE_HW(hdrxinfo->physcpu,sysblk.cpus);
        STORE_HW(hdrxinfo->offown,sizeof(DIAG204_X_HDR));
        STORE_DW(hdrxinfo->diagstck1,ETOD.high);
        STORE_DW(hdrxinfo->diagstck2,ETOD.low);

        /* hercules partition */
        partxinfo = (DIAG204_X_PART*)(hdrxinfo + 1);
        memset(partxinfo, 0, sizeof(DIAG204_PART));
        partxinfo->partnum = sysblk.lparnum;    /* Hercules partition */
        partxinfo->virtcpu = sysblk.cpus;
        get_lparname(partxinfo->partname);
        get_sysname(partxinfo->cpcname);
        get_systype(partxinfo->osname);
        STORE_DW(partxinfo->cssize,sysblk.mainsize);
        STORE_DW(partxinfo->essize,sysblk.xpndsize);
        get_sysplex(partxinfo->gr_name);

        /* hercules cpu's */
        cpuxinfo = (DIAG204_X_PART_CPU*)(partxinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuxinfo, 0, sizeof(DIAG204_X_PART_CPU));
              STORE_HW(cpuxinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuxinfo->index = sysblk.ptyp[i];
              STORE_HW(cpuxinfo->weight,100);

              STORE_DW(cpuxinfo->totdispatch, tCPU[i]);
              STORE_DW(cpuxinfo->effdispatch, uCPU[i]);

              STORE_HW(cpuxinfo->minweight,1000);
              STORE_HW(cpuxinfo->curweight,1000);
              STORE_HW(cpuxinfo->maxweight,1000);

              STORE_DW(cpuxinfo->onlinetime, oCPU[i]);
              STORE_DW(cpuxinfo->waittime,   wCPU[i]);

              STORE_HW(cpuxinfo->pmaweight,1000);
              STORE_HW(cpuxinfo->polarweight,1000);

              cpuxinfo += 1;
          }


#if defined(FEATURE_PHYSICAL_DIAG204)
        /* LPAR management */
        /* FIXME: This section should report on the real CPUs, appearing
         *        and transformed for reporting purposes. This should
         *        also be properly reflected in STSI information.
         */
        partxinfo = (DIAG204_X_PART*)cpuxinfo;
        memset(partxinfo, 0, sizeof(DIAG204_X_PART));
        partxinfo->partnum = 0; /* Physical machine */
        partxinfo->virtcpu = sysblk.cpus;
        memcpy(partxinfo->partname,physical,sizeof(physical));

        /* report all emulated physical cpu's */
        cpuxinfo = (DIAG204_PART_CPU*)(partinfo + 1);
        for(i = 0; i < sysblk.maxcpu; i++)
          if (IS_CPU_ONLINE(i))
          {
              memset(cpuxinfo, 0, sizeof(DIAG204_X_PART_CPU));
              STORE_HW(cpuxinfo->cpaddr,sysblk.regs[i]->cpuad);
              cpuxinfo->index = sysblk.ptyp[i];
              STORE_HW(cpuxinfo->weight,100);

              STORE_DW(cpuxinfo->totdispatch, tCPU[i]);
              STORE_DW(cpuxinfo->effdispatch, uCPU[i]);

              STORE_HW(cpuxinfo->minweight,1000);
              STORE_HW(cpuxinfo->curweight,1000);
              STORE_HW(cpuxinfo->maxweight,1000);

              STORE_DW(cpuxinfo->onlinetime, oCPU[i]);
              STORE_DW(cpuxinfo->waittime,   wCPU[i]);

              STORE_HW(cpuxinfo->pmaweight,1000);
              STORE_HW(cpuxinfo->polarweight,1000);

              cpuxinfo += 1;
          }
#endif /*defined(FEATURE_PHYSICAL_DIAG204)*/

        regs->GR_L(r2) = 0;

        break;
#endif /*defined(FEATURE_EXTENDED_DIAG204)*/

    default:
        PTT_ERR("*DIAG204",regs->GR_L(r1),regs->GR_L(r2),regs->psw.IA_L);
        regs->GR_L(r2) = 4;

    } /*switch(regs->GR_L(r2))*/

} /* end function diag204_call */
Пример #6
0
void ARCH_DEP(sync_mck_interrupt) (REGS *regs)
{
int     rc;                             /* Return code               */
PSA    *psa;                            /* -> Prefixed storage area  */

U64     mcic = MCIC_P  |  /* Instruction processing damage */
               MCIC_WP |
               MCIC_MS |
               MCIC_PM |
               MCIC_IA |
#ifdef FEATURE_HEXADECIMAL_FLOATING_POINT
               MCIC_FP |
#endif /*FEATURE_HEXADECIMAL_FLOATING_POINT*/
               MCIC_GR |
               MCIC_CR |
               MCIC_ST |
#ifdef FEATURE_ACCESS_REGISTERS
               MCIC_AR |
#endif /*FEATURE_ACCESS_REGISTERS*/
#if defined(FEATURE_ESAME) && defined(FEATURE_EXTENDED_TOD_CLOCK)
               MCIC_PR |
#endif /*defined(FEATURE_ESAME) && defined(FEATURE_EXTENDED_TOD_CLOCK)*/
#if defined(FEATURE_BINARY_FLOATING_POINT)
               MCIC_XF |
#endif /*defined(FEATURE_BINARY_FLOATING_POINT)*/
               MCIC_CT |
               MCIC_CC ;
U32     xdmg = 0;
RADR    fsta = 0;


    /* Release intlock if held */
    if (regs->cpuad == sysblk.intowner)
        RELEASE_INTLOCK(regs);

    /* Release mainlock if held */
    if (regs->cpuad == sysblk.mainowner)
        RELEASE_MAINLOCK(regs);

    /* Exit SIE when active */
#if defined(FEATURE_INTERPRETIVE_EXECUTION)
    if(regs->sie_active)
        ARCH_DEP(sie_exit) (regs, SIE_HOST_INTERRUPT);
#endif /*defined(FEATURE_INTERPRETIVE_EXECUTION)*/


    /* Set the main storage reference and change bits */
    STORAGE_KEY(regs->PX, regs) |= (STORKEY_REF | STORKEY_CHANGE);

    /* Point to the PSA in main storage */
    psa = (void*)(regs->mainstor + regs->PX);

    /* Store registers in machine check save area */
    ARCH_DEP(store_status) (regs, regs->PX);

#if !defined(FEATURE_ESAME)
// ZZ
    /* Set the extended logout area to zeros */
    memset(psa->storepsw, 0, 16);
#endif

    /* Store the machine check interrupt code at PSA+232 */
    STORE_DW(psa->mckint, mcic);

    /* Trace the machine check interrupt */
    if (CPU_STEPPING_OR_TRACING(regs, 0))
#if defined(_FEATURE_SIE)
        WRMSG (HHC00824, "I", regs->sie_active ? "IE" : PTYPSTR(regs->cpuad),
            regs->sie_active ? regs->guestregs->cpuad : regs->cpuad, mcic);
#else
        WRMSG (HHC00824, "I", PTYPSTR(regs->cpuad), regs->cpuad, mcic);
#endif

    /* Store the external damage code at PSA+244 */
    STORE_FW(psa->xdmgcode, xdmg);

#if defined(FEATURE_ESAME)
    /* Store the failing storage address at PSA+248 */
    STORE_DW(psa->mcstorad, fsta);
#else /*!defined(FEATURE_ESAME)*/
    /* Store the failing storage address at PSA+248 */
    STORE_FW(psa->mcstorad, fsta);
#endif /*!defined(FEATURE_ESAME)*/

    /* Store current PSW at PSA+X'30' */
    ARCH_DEP(store_psw) ( regs, psa->mckold );

    /* Load new PSW from PSA+X'70' */
    rc = ARCH_DEP(load_psw) ( regs, psa->mcknew );

    if ( rc )
        ARCH_DEP(program_interrupt) (regs, rc);
} /* end function sync_mck_interrupt */
Пример #7
0
/*-------------------------------------------------------------------*/
void ARCH_DEP(store_status) (REGS *ssreg, RADR aaddr)
{
int     i;                              /* Array subscript           */
PSA     *sspsa;                         /* -> Store status area      */

    /* Set reference and change bits */
    STORAGE_KEY(aaddr, ssreg) |= (STORKEY_REF | STORKEY_CHANGE);
#if defined(FEATURE_ESAME)
    /* The ESAME PSA is two pages in size */
    if(!aaddr)
        STORAGE_KEY(aaddr + 4096, ssreg) |= (STORKEY_REF | STORKEY_CHANGE);
#endif /*defined(FEATURE_ESAME)*/

#if defined(FEATURE_ESAME)
    /* For store status at address, we must adjust the PSA offset */
    /* ZZ THIS TEST IS NOT CONCLUSIVE */
    if(aaddr != 0 && aaddr != ssreg->PX)
        aaddr -= 512 + 4096 ;
#endif

    aaddr &= 0x7FFFFE00;

    /* Point to the PSA into which status is to be stored */
    sspsa = (void*)(ssreg->mainstor + aaddr);

    /* Store CPU timer in bytes 216-223 */
    STORE_DW(sspsa->storeptmr, cpu_timer(ssreg));

    /* Store clock comparator in bytes 224-231 */
#if defined(FEATURE_ESAME)
    STORE_DW(sspsa->storeclkc, ssreg->clkc);
#else /*defined(FEATURE_ESAME)*/
    STORE_DW(sspsa->storeclkc, ssreg->clkc << 8);
#endif /*defined(FEATURE_ESAME)*/

    /* Store PSW in bytes 256-263 */
    ARCH_DEP(store_psw) (ssreg, sspsa->storepsw);

    /* Store prefix register in bytes 264-267 */
    STORE_FW(sspsa->storepfx,ssreg->PX);

#if defined(FEATURE_ESAME)
    /* Store Floating Point Control Register */
    STORE_FW(sspsa->storefpc,ssreg->fpc);

    /* Store TOD Programable register */
    STORE_FW(sspsa->storetpr,ssreg->todpr);
#endif /*defined(FEATURE_ESAME)*/

#if defined(_900)
    /* Only store the arch mode indicator for a PSA type store status */
    if(!aaddr)
#if defined(FEATURE_ESAME)
        sspsa->arch = 1;
#else /*defined(FEATURE_ESAME)*/
        sspsa->arch = 0;
#endif /*defined(FEATURE_ESAME)*/
#endif /*defined(_900)*/

    /* Store access registers in bytes 288-351 */
    for (i = 0; i < 16; i++)
        STORE_FW(sspsa->storear[i],ssreg->AR(i));

    /* Store floating-point registers in bytes 352-383 */
#if defined(FEATURE_ESAME)
    for (i = 0; i < 32; i++)
#else /*!defined(FEATURE_ESAME)*/
    for (i = 0; i < 8; i++)
#endif /*!defined(FEATURE_ESAME)*/
        STORE_FW(sspsa->storefpr[i],ssreg->fpr[i]);

    /* Store general-purpose registers in bytes 384-447 */
    for (i = 0; i < 16; i++)
        STORE_W(sspsa->storegpr[i],ssreg->GR(i));

    /* Store control registers in bytes 448-511 */
    for (i = 0; i < 16; i++)
        STORE_W(sspsa->storecr[i],ssreg->CR(i));

} /* end function store_status */
Пример #8
0
/*-------------------------------------------------------------------*/
void ARCH_DEP(perform_external_interrupt) (REGS *regs)
{
PSA    *psa;                            /* -> Prefixed storage area  */
U16     cpuad;                          /* Originating CPU address   */
#if defined(FEATURE_VM_BLOCKIO)
#if defined(FEATURE_ESAME)
RADR    servpadr;      /* Address of 64-bit block I/O interrupt */
#endif
U16     servcode;      /* Service Signal or Block I/O Interrupt code */
#endif /* defined(FEATURE_VM_BLOCKIO) */

    /* External interrupt if console interrupt key was depressed */
    if ( OPEN_IC_INTKEY(regs) && !SIE_MODE(regs) )
    {
        WRMSG (HHC00840, "I");

        /* Reset interrupt key pending */
        OFF_IC_INTKEY;

        /* Generate interrupt key interrupt */
        ARCH_DEP(external_interrupt) (EXT_INTERRUPT_KEY_INTERRUPT, regs);
    }

    /* External interrupt if malfunction alert is pending */
    if (OPEN_IC_MALFALT(regs))
    {
        /* Find first CPU which generated a malfunction alert */
        for (cpuad = 0; regs->malfcpu[cpuad] == 0; cpuad++)
        {
            if (cpuad >= sysblk.maxcpu)
            {
                OFF_IC_MALFALT(regs);
                return;
            }
        } /* end for(cpuad) */

// /*debug*/ logmsg (_("External interrupt: Malfuction Alert from CPU %d\n"),
// /*debug*/    cpuad);

        /* Reset the indicator for the CPU which was found */
        regs->malfcpu[cpuad] = 0;

        /* Store originating CPU address at PSA+X'84' */
        psa = (void*)(regs->mainstor + regs->PX);
        STORE_HW(psa->extcpad,cpuad);

        /* Reset emergency signal pending flag if there are
           no other CPUs which generated emergency signal */
        OFF_IC_MALFALT(regs);
        while (++cpuad < sysblk.maxcpu)
        {
            if (regs->malfcpu[cpuad])
            {
                ON_IC_MALFALT(regs);
                break;
            }
        } /* end while */

        /* Generate emergency signal interrupt */
        ARCH_DEP(external_interrupt) (EXT_MALFUNCTION_ALERT_INTERRUPT, regs);
    }


    /* External interrupt if emergency signal is pending */
    if (OPEN_IC_EMERSIG(regs))
    {
        /* Find first CPU which generated an emergency signal */
        for (cpuad = 0; regs->emercpu[cpuad] == 0; cpuad++)
        {
            if (cpuad >= sysblk.maxcpu)
            {
                OFF_IC_EMERSIG(regs);
                return;
            }
        } /* end for(cpuad) */

// /*debug*/ logmsg (_("External interrupt: Emergency Signal from CPU %d\n"),
// /*debug*/    cpuad);

        /* Reset the indicator for the CPU which was found */
        regs->emercpu[cpuad] = 0;

        /* Store originating CPU address at PSA+X'84' */
        psa = (void*)(regs->mainstor + regs->PX);
        STORE_HW(psa->extcpad,cpuad);

        /* Reset emergency signal pending flag if there are
           no other CPUs which generated emergency signal */
        OFF_IC_EMERSIG(regs);
        while (++cpuad < sysblk.maxcpu)
        {
            if (regs->emercpu[cpuad])
            {
                ON_IC_EMERSIG(regs);
                break;
            }
        } /* end while */

        /* Generate emergency signal interrupt */
        ARCH_DEP(external_interrupt) (EXT_EMERGENCY_SIGNAL_INTERRUPT, regs);
    }

    /* External interrupt if external call is pending */
    if (OPEN_IC_EXTCALL(regs))
    {
//  /*debug*/logmsg (_("External interrupt: External Call from CPU %d\n"),
//  /*debug*/       regs->extccpu);

        /* Reset external call pending */
        OFF_IC_EXTCALL(regs);

        /* Store originating CPU address at PSA+X'84' */
        psa = (void*)(regs->mainstor + regs->PX);
        STORE_HW(psa->extcpad,regs->extccpu);

        /* Generate external call interrupt */
        ARCH_DEP(external_interrupt) (EXT_EXTERNAL_CALL_INTERRUPT, regs);
    }

    /* External interrupt if TOD clock exceeds clock comparator */
    if ( tod_clock(regs) > regs->clkc
        && OPEN_IC_CLKC(regs) )
    {
        if (CPU_STEPPING_OR_TRACING_ALL)
        {
            WRMSG (HHC00841, "I");
        }
        ARCH_DEP(external_interrupt) (EXT_CLOCK_COMPARATOR_INTERRUPT, regs);
    }

    /* External interrupt if CPU timer is negative */
    if ( CPU_TIMER(regs) < 0
        && OPEN_IC_PTIMER(regs) )
    {
        if (CPU_STEPPING_OR_TRACING_ALL)
        {
            WRMSG (HHC00842, "I", CPU_TIMER(regs) << 8);
        }
        ARCH_DEP(external_interrupt) (EXT_CPU_TIMER_INTERRUPT, regs);
    }

    /* External interrupt if interval timer interrupt is pending */
#if defined(FEATURE_INTERVAL_TIMER)
    if (OPEN_IC_ITIMER(regs)
#if defined(_FEATURE_SIE)
        && !(SIE_STATB(regs, M, ITMOF))
#endif /*defined(_FEATURE_SIE)*/
        )
    {
        if (CPU_STEPPING_OR_TRACING_ALL)
        {
            WRMSG (HHC00843, "I");
        }
        OFF_IC_ITIMER(regs);
        ARCH_DEP(external_interrupt) (EXT_INTERVAL_TIMER_INTERRUPT, regs);
    }

#if defined(FEATURE_ECPSVM)
    if ( OPEN_IC_ECPSVTIMER(regs) )
    {
        OFF_IC_ECPSVTIMER(regs);
        ARCH_DEP(external_interrupt) (EXT_VINTERVAL_TIMER_INTERRUPT,regs);
    }
#endif /*FEATURE_ECPSVM*/
#endif /*FEATURE_INTERVAL_TIMER*/

    /* External interrupt if service signal is pending */
    if ( OPEN_IC_SERVSIG(regs) && !SIE_MODE(regs) )
    {

#if defined(FEATURE_VM_BLOCKIO)
        
        /* Note: Both Block I/O and Service Signal are enabled by the */
        /* the same CR0 bit.  Hence they are handled in the same code */
        switch(sysblk.servcode)
        {
        case EXT_BLOCKIO_INTERRUPT:  /* VM Block I/O Interrupt */

           if (sysblk.biodev->ccwtrace)
           {
           WRMSG (HHC00844, "I",
                SSID_TO_LCSS(sysblk.biodev->ssid),
                sysblk.biodev->devnum,
                sysblk.servcode,
                sysblk.bioparm,
                sysblk.biostat,
                sysblk.biosubcd
                );
           }

           servcode = EXT_BLOCKIO_INTERRUPT;

#if defined(FEATURE_ESAME)
/* Real address used to store the 64-bit interrupt parameter */
#define VM_BLOCKIO_INT_PARM 0x11B8
           if (sysblk.biosubcd == 0x07)
           {
           /* 8-byte interrupt parm */
           
               if (CPU_STEPPING_OR_TRACING_ALL)
               {
                  char buf[40];
                  MSGBUF(buf, "%16.16X", (unsigned) sysblk.bioparm);
                  WRMSG (HHC00845,"I", buf);
               }

               /* Set the main storage reference and change bits   */
               /* for 64-bit interruption parameter.               */
               /* Note: This is handled for the first 4K page in   */
               /* ARCH_DEP(external_interrupt), but not for the    */
               /* the second 4K page used for the 64-bit interrupt */
               /* parameter.                                       */

               /* Point to 2nd page of PSA in main storage */
               servpadr=APPLY_PREFIXING(VM_BLOCKIO_INT_PARM,regs->PX);

               STORAGE_KEY(servpadr, regs) 
                     |= (STORKEY_REF | STORKEY_CHANGE);

#if 0
               /* Store the 64-bit interrupt parameter */
               logmsg (_("Saving 64-bit Block I/O interrupt parm at "
                         "%16.16X: %16.16X\n"),
                         servpadr,
                         sysblk.bioparm
                      );
#endif

               STORE_DW(regs->mainstor + servpadr,sysblk.bioparm);
               psa = (void*)(regs->mainstor + regs->PX);
           }
           else
           {
#endif  /* defined(FEATURE_ESAME) */

           /* 4-byte interrupt parm */

              if (CPU_STEPPING_OR_TRACING_ALL)
              {
                 char buf[40];
                 MSGBUF(buf, "%8.8X", (U32) sysblk.bioparm);
                 WRMSG (HHC00845,"I", buf);
              }

              /* Store Block I/O parameter at PSA+X'80' */
              psa = (void*)(regs->mainstor + regs->PX);
              STORE_FW(psa->extparm,(U32)sysblk.bioparm);

#if defined(FEATURE_ESAME)
           }
#endif

           /* Store sub-interruption code and status at PSA+X'84' */
           STORE_HW(psa->extcpad,(sysblk.biosubcd<<8)|sysblk.biostat);
           
           /* Reset interruption data */
           sysblk.bioparm  = 0;
           sysblk.biosubcd = 0;
           sysblk.biostat  = 0;
           
           break;

        case EXT_SERVICE_SIGNAL_INTERRUPT: /* Service Signal */
        default:
             servcode = EXT_SERVICE_SIGNAL_INTERRUPT;
             
            /* Apply prefixing if the parameter is a storage address */
            if ( (sysblk.servparm & SERVSIG_ADDR) )
                sysblk.servparm =
                     APPLY_PREFIXING (sysblk.servparm, regs->PX);

             if (CPU_STEPPING_OR_TRACING_ALL)
             {
                 WRMSG (HHC00846,"I", sysblk.servparm);
             }

             /* Store service signal parameter at PSA+X'80' */
             psa = (void*)(regs->mainstor + regs->PX);
             STORE_FW(psa->extparm,sysblk.servparm);

        }  /* end switch(sysblk.servcode) */
        /* Reset service parameter */
        sysblk.servparm = 0;

        /* Reset service code */
        sysblk.servcode = 0;

        /* Reset service signal pending */
        OFF_IC_SERVSIG;

        /* Generate service signal interrupt */
        ARCH_DEP(external_interrupt) (servcode, regs);
             
#else /* defined(FEATURE_VM_BLOCKIO) */

        /* Apply prefixing if the parameter is a storage address */
        if ( (sysblk.servparm & SERVSIG_ADDR) )
            sysblk.servparm =
                APPLY_PREFIXING (sysblk.servparm, regs->PX);

        if (CPU_STEPPING_OR_TRACING_ALL)
        {
            WRMSG (HHC00846,"I", sysblk.servparm);
        }

        /* Store service signal parameter at PSA+X'80' */
        psa = (void*)(regs->mainstor + regs->PX);
        STORE_FW(psa->extparm,sysblk.servparm);

        /* Reset service parameter */
        sysblk.servparm = 0;

        /* Reset service signal pending */
        OFF_IC_SERVSIG;
        
        /* Generate service signal interrupt */
        ARCH_DEP(external_interrupt) (EXT_SERVICE_SIGNAL_INTERRUPT, regs);

#endif /* defined(FEATURE_VM_BLOCKIO) */

    }  /* end OPEN_IC_SERVSIG(regs) */

} /* end function perform_external_interrupt */