/** * TimeDate Screen displays current time and date, uptime, OS ver... * *\verbatim * * +--------------------+ +--------------------+ * |## Linux 2.6.11 ###@| |### TIME: myhost ##@| * |Up xxx days hh:mm:ss| |17.05.2005 11:32:57a| * | Wed May 17, 1998 | +--------------------+ * |11:32:57a 100% idle| * +--------------------+ * *\endverbatim * * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags * \return Always 0 */ int time_screen(int rep, int display, int *flags_ptr) { char now[40]; char today[40]; int xoffs; int days, hour, min, sec; static int heartbeat = 0; static const char *timeFormat = NULL; static const char *dateFormat = NULL; time_t thetime; struct tm *rtime; double uptime, idle; if ((*flags_ptr & INITIALIZED) == 0) { *flags_ptr |= INITIALIZED; /* get config values */ timeFormat = config_get_string("TimeDate", "TimeFormat", 0, "%H:%M:%S"); dateFormat = config_get_string("TimeDate", "DateFormat", 0, "%b %d %Y"); sock_send_string(sock, "screen_add T\n"); sock_printf(sock, "screen_set T -name {Time Screen: %s}\n", get_hostname()); sock_send_string(sock, "widget_add T title title\n"); sock_send_string(sock, "widget_add T one string\n"); if (lcd_hgt >= 4) { sock_send_string(sock, "widget_add T two string\n"); sock_send_string(sock, "widget_add T three string\n"); /* write title bar: OS name, OS version, hostname */ sock_printf(sock, "widget_set T title {%s %s: %s}\n", get_sysname(), get_sysrelease(), get_hostname()); } else { /* write title bar: hostname */ sock_printf(sock, "widget_set T title {TIME: %s}\n", get_hostname()); } } /* toggle colon display */ heartbeat ^= 1; time(&thetime); rtime = localtime(&thetime); if (strftime(today, sizeof(today), dateFormat, rtime) == 0) *today = '\0'; if (strftime(now, sizeof(now), timeFormat, rtime) == 0) *now = '\0'; tickTime(now, heartbeat); if (lcd_hgt >= 4) { char tmp[40]; /* should be large enough */ machine_get_uptime(&uptime, &idle); /* display the uptime... */ days = (int) uptime / 86400; hour = ((int) uptime % 86400) / 3600; min = ((int) uptime % 3600) / 60; sec = ((int) uptime % 60); if (lcd_wid >= 20) sprintf(tmp, "Up %3d day%s %02d:%02d:%02d", days, ((days != 1) ? "s" : ""), hour, min, sec); else sprintf(tmp, "Up %dd %02d:%02d:%02d", days, hour, min, sec); xoffs = (lcd_wid > strlen(tmp)) ? ((lcd_wid - strlen(tmp)) / 2) + 1 : 1; if (display) sock_printf(sock, "widget_set T one %i 2 {%s}\n", xoffs, tmp); /* display the date */ xoffs = (lcd_wid > strlen(today)) ? ((lcd_wid - strlen(today)) / 2) + 1 : 1; if (display) sock_printf(sock, "widget_set T two %i 3 {%s}\n", xoffs, today); /* display the time & idle time... */ sprintf(tmp, "%s %3i%% idle", now, (int) idle); xoffs = (lcd_wid > strlen(tmp)) ? ((lcd_wid - strlen(tmp)) / 2) + 1 : 1; if (display) sock_printf(sock, "widget_set T three %i 4 {%s}\n", xoffs, tmp); } else { /* 2 line version of the screen */ xoffs = (lcd_wid > (strlen(today) + strlen(now) + 1)) ? ((lcd_wid - ((strlen(today) + strlen(now) + 1))) / 2) + 1 : 1; if (display) sock_printf(sock, "widget_set T one %i 2 {%s %s}\n", xoffs, today, now); } return 0; } /* End time_screen() */
/*-------------------------------------------------------------------*/ 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 */
/** * Uptime Screen shows info about system uptime and OS version * *\verbatim * * +--------------------+ +--------------------+ * |## SYSTEM UPTIME ##@| |# Linux 2.6.11: my#@| * | myhost | | xxx days hh:mm:ss | * | xxx days hh:mm:ss | +--------------------+ * | Linux 2.6.11 | * +--------------------+ * *\endverbatim * * \param rep Time since last screen update * \param display 1 if screen is visible or data should be updated * \param flags_ptr Mode flags * \return Always 0 */ int uptime_screen(int rep, int display, int *flags_ptr) { int xoffs; int days, hour, min, sec; double uptime, idle; static int heartbeat = 0; char tmp[257]; /* should be large enough for host name */ if ((*flags_ptr & INITIALIZED) == 0) { *flags_ptr |= INITIALIZED; sock_send_string(sock, "screen_add U\n"); sock_printf(sock, "screen_set U -name {Uptime Screen: %s}\n", get_hostname()); sock_send_string(sock, "widget_add U title title\n"); if (lcd_hgt >= 4) { sock_send_string(sock, "widget_add U one string\n"); sock_send_string(sock, "widget_add U two string\n"); sock_send_string(sock, "widget_add U three string\n"); sock_send_string(sock, "widget_set U title {SYSTEM UPTIME}\n"); sprintf(tmp, "%s", get_hostname()); xoffs = (lcd_wid > strlen(tmp)) ? (((lcd_wid - strlen(tmp)) / 2) + 1) : 1; sock_printf(sock, "widget_set U one %i 2 {%s}\n", xoffs, tmp); sprintf(tmp, "%s %s", get_sysname(), get_sysrelease()); xoffs = (lcd_wid > strlen(tmp)) ? (((lcd_wid - strlen(tmp)) / 2) + 1) : 1; sock_printf(sock, "widget_set U three %i 4 {%s}\n", xoffs, tmp); } else { sock_send_string(sock, "widget_add U one string\n"); sock_printf(sock, "widget_set U title {%s %s: %s}\n", get_sysname(), get_sysrelease(), get_hostname()); } } /* toggle colon display */ heartbeat ^= 1; machine_get_uptime(&uptime, &idle); days = (int) uptime / 86400; hour = ((int) uptime % 86400) / 3600; min = ((int) uptime % 3600) / 60; sec = ((int) uptime % 60); if (lcd_wid >= 20) sprintf(tmp, "%d day%s %02d:%02d:%02d", days, ((days != 1) ? "s" : ""), hour, min, sec); else sprintf(tmp, "%dd %02d:%02d:%02d", days, hour, min, sec); if (display) { xoffs = (lcd_wid > strlen(tmp)) ? (((lcd_wid - strlen(tmp)) / 2) + 1) : 1; if (lcd_hgt >= 4) sock_printf(sock, "widget_set U two %d 3 {%s}\n", xoffs, tmp); else sock_printf(sock, "widget_set U one %d 2 {%s}\n", xoffs, tmp); } return 0; } /* End uptime_screen() */
/*-------------------------------------------------------------------*/ 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 */