diff --git a/dumpstate/dump_power.cpp b/dumpstate/dump_power.cpp index 75468f8..9c3d9d4 100644 --- a/dumpstate/dump_power.cpp +++ b/dumpstate/dump_power.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#include -#include #include #include #include @@ -25,13 +23,11 @@ #include #include #include -#include -#include #include #include #include "DumpstateUtil.h" -#include "dump_power.h" + void printTitle(const char *msg) { printf("\n------ %s ------\n", msg); @@ -614,371 +610,6 @@ void dumpMitigation() { } } -bool readSysfsToDouble(const std::string &path, double *val) { - std::string file_contents; - - if (!android::base::ReadFileToString(path, &file_contents)) { - return false; - } else if (sscanf(file_contents.c_str(), "%lf", val) != 1) { - return false; - } - return true; -} - -void readLPFPowerBitResolutions(const char *odpmDir, double *bitResolutions) { - char path[128]; - - for (int i = 0; i < METER_CHANNEL_MAX; i++) { - snprintf(path, 128, "%s/in_power%d_scale", odpmDir, i); - if (!readSysfsToDouble(path, &bitResolutions[i])) { - /* using large negative value to notify this odpm value is invalid */ - bitResolutions[i] = -1000; - } - } -} - -void readLPFChannelNames(const char *odpmEnabledRailsPath, char **lpfChannelNames) { - char *line = NULL; - size_t len = 0; - ssize_t read; - - FILE *fp = fopen(odpmEnabledRailsPath, "r"); - if (fp == NULL) - return; - - int c = 0; - while ((read = getline(&line, &len, fp)) != -1 && read != 0) { - lpfChannelNames[c] = (char *)malloc(read); - if (lpfChannelNames[c] != nullptr) { - snprintf(lpfChannelNames[c], read, "%s", line); - } - if (++c == METER_CHANNEL_MAX) - break; - } - fclose(fp); - - if (line) - free(line); -} - -int getMainPmicID(const char *mainPmicNamePath, const char *mainPmicName) { - std::string content; - int ret = 0; - - if (!android::base::ReadFileToString(mainPmicNamePath, &content)) { - printf("Failed to open %s, set device0 as main pmic\n", mainPmicNamePath); - return ret; - } - - if (strcmp(content.c_str(), mainPmicName) != 0) { - ret = 1; - } - - return ret; -} - -void freeLpfChannelNames(char **lpfChannelNames) { - for (int c = 0; c < METER_CHANNEL_MAX; c++){ - free(lpfChannelNames[c]); - } -} - -void printUTC(struct timespec time, const char *stat) { - char timeBuff[128]; - if (strlen(stat) > 0) { - printf("%s: ", stat); - } - std::strftime(timeBuff, sizeof(timeBuff), "%m/%d/%Y_%H:%M:%S", std::localtime(&time.tv_sec)); - printf("%s.%lu",timeBuff, time.tv_nsec); -} - -void printUTC(timeval time, const char *stat) { - char timeBuff[128]; - if (strlen(stat) > 0) { - printf("%s: ", stat); - } - std::strftime(timeBuff, sizeof(timeBuff), "%m/%d/%Y_%H:%M:%S", std::localtime(&time.tv_sec)); - /* convert usec to nsec */ - printf("%s.%lu000",timeBuff, time.tv_usec); -} - -void printODPMChannelSummary(std::vector &odpmData, - double *lpfBitResolutions, char **lpfChannelNames) { - std::vector validTime; - std::vector instPower[METER_CHANNEL_MAX]; - std::vector instPowerMax; - std::vector instPowerMin; - std::vector instPowerList; - std::vector instPowerStd; - - if (odpmData.size() == 0) - return; - - /* initial Max, Min, Sum for sorting*/ - timespec curTime = odpmData[0].time; - validTime.emplace_back(curTime); - for (int c = 0; c < METER_CHANNEL_MAX; c++) { - double power = lpfBitResolutions[c] * odpmData[0].value[c]; - instPower[c].emplace_back((OdpmInstantPower){curTime, power}); - instPowerMax.emplace_back((OdpmInstantPower){curTime, power}); - instPowerMin.emplace_back((OdpmInstantPower){curTime, power}); - instPowerList.emplace_back(power); - } - - for (auto lpf = (odpmData.begin() + 1); lpf != odpmData.end(); lpf++) { - curTime = lpf->time; - /* remove duplicate data by checking the odpm instant data dump time */ - auto it = std::find_if(validTime.begin(), validTime.end(), - [&_ts = curTime] (const timespec &ts) -> - bool {return _ts.tv_sec == ts.tv_sec && _ts.tv_nsec == ts.tv_nsec;}); - if (it == validTime.end()) { - validTime.emplace_back(curTime); - for (int c = 0; c < METER_CHANNEL_MAX; c++){ - double power = lpfBitResolutions[c] * lpf->value[c]; - instPower[c].emplace_back((OdpmInstantPower){curTime, power}); - instPowerList[c] += power; - if (power > instPowerMax[c].value) { - instPowerMax[c].value = power; - instPowerMax[c].time = curTime; - } - if (power < instPowerMin[c].value) { - instPowerMin[c].value = power; - instPowerMin[c].time = curTime; - } - } - } - } - - int n = validTime.size(); - for (int c = 0; c < METER_CHANNEL_MAX; c++) { - /* sort instant power by time */ - std::sort(instPower[c].begin(), instPower[c].end(), - [] (const auto &i, const auto &j) - {return i.time.tv_sec <= j.time.tv_sec && i.time.tv_nsec < j.time.tv_nsec;}); - /* compute std for each channel */ - double avg = instPowerList[c] / n; - double mse = 0; - for (int i = 0; i < n; i++) { - mse += pow(instPower[c][i].value - avg, 2); - } - instPowerStd.emplace_back(pow(mse / n, 0.5)); - } - - /* print Max, Min, Avg, Std */ - for (int c = 0; c < METER_CHANNEL_MAX; c++) { - printf("%s Max: %.2f Min: %.2f Avg: %.2f Std: %.2f\n", lpfChannelNames[c], - instPowerMax[c].value, - instPowerMin[c].value, - instPowerList[c] / n, - instPowerStd[c]); - } - printf("\n"); - - /* print time */ - printf("time "); - for (int i = 0; i < n; i++) { - printUTC(instPower[0][i].time, ""); - printf(" "); - } - printf("\n"); - - /* print instant power by channel */ - for (int c = 0; c < METER_CHANNEL_MAX; c++){ - printf("%s ", lpfChannelNames[c]); - for (int i = 0; i < n; i++) { - printf("%.2f ", instPower[c][i].value); - } - printf("\n"); - } - - printf("\n"); -} - -void printLatency(const struct BrownoutStatsExtend *brownoutStatsExtend) { - /* received latency */ - timespec recvLatency; - recvLatency.tv_sec = brownoutStatsExtend[0].eventReceivedTime.tv_sec - \ - brownoutStatsExtend[0].brownoutStats.triggered_time.tv_sec; - - signed long long temp = brownoutStatsExtend[0].eventReceivedTime.tv_usec * 1000; - if (temp >= brownoutStatsExtend[0].brownoutStats.triggered_time.tv_nsec) - recvLatency.tv_nsec = brownoutStatsExtend[0].eventReceivedTime.tv_usec * 1000 - \ - brownoutStatsExtend[0].brownoutStats.triggered_time.tv_nsec; - else - recvLatency.tv_nsec = NSEC_PER_SEC - \ - brownoutStatsExtend[0].brownoutStats.triggered_time.tv_nsec \ - + brownoutStatsExtend[0].eventReceivedTime.tv_usec * 1000; - - /* dump latency */ - timespec dumpLatency; - dumpLatency.tv_sec = brownoutStatsExtend[0].dumpTime.tv_sec - \ - brownoutStatsExtend[0].eventReceivedTime.tv_sec; - - temp = brownoutStatsExtend[0].dumpTime.tv_usec; - if (temp >= brownoutStatsExtend[0].eventReceivedTime.tv_usec) - dumpLatency.tv_nsec = (brownoutStatsExtend[0].dumpTime.tv_usec - \ - brownoutStatsExtend[0].eventReceivedTime.tv_usec) * 1000; - else - dumpLatency.tv_nsec = NSEC_PER_SEC - \ - brownoutStatsExtend[0].eventReceivedTime.tv_usec * 1000 + \ - brownoutStatsExtend[0].dumpTime.tv_usec * 1000; - - /* total latency */ - timespec totalLatency; - totalLatency.tv_sec = brownoutStatsExtend[0].dumpTime.tv_sec - \ - brownoutStatsExtend[0].brownoutStats.triggered_time.tv_sec; - temp = brownoutStatsExtend[0].dumpTime.tv_usec * 1000; - if (temp >= brownoutStatsExtend[0].brownoutStats.triggered_time.tv_nsec) - totalLatency.tv_nsec = brownoutStatsExtend[0].dumpTime.tv_usec * 1000 - \ - brownoutStatsExtend[0].brownoutStats.triggered_time.tv_nsec; - else - totalLatency.tv_nsec = NSEC_PER_SEC - \ - brownoutStatsExtend[0].brownoutStats.triggered_time.tv_nsec + \ - brownoutStatsExtend[0].dumpTime.tv_usec * 1000; - - printf("recvLatency %ld.%09ld\n", recvLatency.tv_sec, recvLatency.tv_nsec); - printf("dumpLatency %ld.%09ld\n", dumpLatency.tv_sec, dumpLatency.tv_nsec); - printf("totalLatency %ld.%09ld\n\n", totalLatency.tv_sec, totalLatency.tv_nsec); - -} - -void printBRStatsSummary(const struct BrownoutBinaryStatsConfig cfg, - const struct BrownoutStatsExtend *brownoutStatsExtend) { - int mainPmicID = 0; - mainPmicID = getMainPmicID(cfg.pmic[mainPmicID].PmicNamePath, cfg.pmic[mainPmicID].PmicName); - int subPmicID = !mainPmicID; - double mainLpfBitResolutions[METER_CHANNEL_MAX]; - double subLpfBitResolutions[METER_CHANNEL_MAX]; - char *mainLpfChannelNames[METER_CHANNEL_MAX]; - char *subLpfChannelNames[METER_CHANNEL_MAX]; - std::vector odpmData[2]; - - /* print out the triggered_time in first dump */ - printUTC(brownoutStatsExtend[0].brownoutStats.triggered_time, "triggered_time"); - printf("\n"); - printf("triggered_idx: %d\n", brownoutStatsExtend[0].brownoutStats.triggered_idx); - printLatency(brownoutStatsExtend); - - /* skip time invalid odpm instant data */ - for (int i = 0; i < DUMP_TIMES; i++) { - for (int d = 0; d < DATA_LOGGING_LEN; d++) { - if (brownoutStatsExtend[i].brownoutStats.main_odpm_instant_data[d].time.tv_sec != 0) { - odpmData[mainPmicID].emplace_back(brownoutStatsExtend[i].brownoutStats.main_odpm_instant_data[d]); - } - if (brownoutStatsExtend[i].brownoutStats.sub_odpm_instant_data[d].time.tv_sec != 0) { - odpmData[subPmicID].emplace_back(brownoutStatsExtend[i].brownoutStats.sub_odpm_instant_data[d]); - } - } - } - - /* read odpm resolutions and channel names */ - readLPFPowerBitResolutions(cfg.pmic[mainPmicID].OdpmDir, mainLpfBitResolutions); - readLPFPowerBitResolutions(cfg.pmic[subPmicID].OdpmDir, subLpfBitResolutions); - readLPFChannelNames(cfg.pmic[mainPmicID].OdpmEnabledRailsPath, mainLpfChannelNames); - readLPFChannelNames(cfg.pmic[subPmicID].OdpmEnabledRailsPath, subLpfChannelNames); - - printODPMChannelSummary(odpmData[mainPmicID], mainLpfBitResolutions, mainLpfChannelNames); - printODPMChannelSummary(odpmData[subPmicID], subLpfBitResolutions, subLpfChannelNames); - - freeLpfChannelNames(mainLpfChannelNames); - freeLpfChannelNames(subLpfChannelNames); -} - -void printOdpmInstantData(struct odpm_instant_data odpmInstantData) { - if (odpmInstantData.time.tv_sec == 0 && - odpmInstantData.time.tv_nsec == 0) { - return; - } - printUTC(odpmInstantData.time, ""); - for (int i = 0; i < METER_CHANNEL_MAX; i++){ - printf("%d ", odpmInstantData.value[i]); - } - printf("\n"); -} - -void printBRStats(struct BrownoutStatsExtend *brownoutStatsExtend) { - printUTC(brownoutStatsExtend->brownoutStats.triggered_time, "triggered_time"); - printf("\n"); - printf("triggered_idx: %d\n", brownoutStatsExtend->brownoutStats.triggered_idx); - - printf("main_odpm_instant_data: \n"); - for (int d = 0; d < DATA_LOGGING_LEN; d++) { - printOdpmInstantData(brownoutStatsExtend->brownoutStats.main_odpm_instant_data[d]); - } - printf("sub_odpm_instant_data: \n"); - for (int d = 0; d < DATA_LOGGING_LEN; d++) { - printOdpmInstantData(brownoutStatsExtend->brownoutStats.sub_odpm_instant_data[d]); - } - - printf("\n"); - printf("fvp_stats:\n"); - printf("%s\n\n", brownoutStatsExtend->fvpStats); - printf("pcie_modem:\n"); - printf("%s\n\n", brownoutStatsExtend->pcieModem); - printf("pcie_wifi:\n"); - printf("%s\n\n", brownoutStatsExtend->pcieWifi); - for (int i = 0; i < STATS_MAX_SIZE; i++) { - if (strlen(brownoutStatsExtend->numericStats[i].name) > 0) - printf("%s: %d\n", brownoutStatsExtend->numericStats[i].name, - brownoutStatsExtend->numericStats[i].value); - } - printUTC(brownoutStatsExtend->eventReceivedTime, "eventReceivedTime"); - printf("\n"); - printUTC(brownoutStatsExtend->dumpTime, "dumpTime"); - printf("\n"); - printf("eventIdx: %d\n", brownoutStatsExtend->eventIdx); -} - -void dumpBRStats(const struct BrownoutBinaryStatsConfig cfg, - const char* logPath, const char *title) { - struct BrownoutStatsExtend brownoutStatsExtend[DUMP_TIMES]; - size_t memSize = sizeof(struct BrownoutStatsExtend) * DUMP_TIMES; - - int fd = open(logPath, O_RDONLY); - if (fd < 0) { - printf("Failed to open %s\n", logPath); - return; - } - - size_t logFileSize = lseek(fd, 0, SEEK_END); - if (memSize != logFileSize) { - printf("Invalid log size!\n"); - printf("BrownoutStatsExtend size: %lu\n", memSize); - printf("%s size: %lu\n", title, logFileSize); - close(fd); - return; - } - - char *logFileAddr = (char *) mmap(NULL, logFileSize, PROT_READ, MAP_PRIVATE, fd, 0); - close(fd); - - memcpy(&brownoutStatsExtend, logFileAddr, logFileSize); - munmap(logFileAddr, logFileSize); - - printTitle(title); - printBRStatsSummary(cfg, brownoutStatsExtend); - - printf("== RAW ==\n"); - for (int i = 0; i < DUMP_TIMES; i++) { - printf("== Dump %d ==\n", i); - printBRStats(&brownoutStatsExtend[i]); - printf("=============\n\n"); - } -} - -void dumpMitigationBinaryStats(const struct BrownoutBinaryStatsConfig cfg) { - if (access(cfg.StoringPath, F_OK) != 0) { - printf("Failed to access %s\n", cfg.StoringPath); - } else { - dumpBRStats(cfg, cfg.StoringPath, cfg.ThismealFileName); - } - if (access(cfg.BackupPath, F_OK) != 0) { - printf("Failed to access %s\n", cfg.StoringPath); - } else { - dumpBRStats(cfg, cfg.BackupPath, cfg.LastmealFileName); - } -} - void dumpMitigationStats() { int ret; const char *directory = "/sys/devices/virtual/pmic/mitigation/last_triggered_count/"; @@ -1278,29 +909,6 @@ void dumpIrqDurationCounts() { } int main() { - const struct BrownoutBinaryStatsConfig cfg = { - .StoringPath = "/data/vendor/mitigation/thismeal.bin", - .BackupPath = "/data/vendor/mitigation/lastmeal.bin", - .ThismealFileName = "thismeal.bin", - .LastmealFileName = "lastmeal.bin", - .pmic = { - /* Main Pmic */ - { - .OdpmDir = "/sys/bus/iio/devices/iio:device0", - .OdpmEnabledRailsPath = "/sys/bus/iio/devices/iio:device0/enabled_rails", - .PmicNamePath = "/sys/bus/iio/devices/iio:device0/name", - .PmicName = "s2mpg14-odpm\n", - }, - /* Sub Pmic */ - { - .OdpmDir = "/sys/bus/iio/devices/iio:device1", - .OdpmEnabledRailsPath = "/sys/bus/iio/devices/iio:device1/enabled_rails", - .PmicNamePath = "/sys/bus/iio/devices/iio:device1/name", - .PmicName = "s2mpg15-odpm\n", - }, - }, - }; - dumpPowerStatsTimes(); dumpAcpmStats(); dumpPowerSupplyStats(); @@ -1320,6 +928,5 @@ int main() { dumpMitigationStats(); dumpMitigationDirs(); dumpIrqDurationCounts(); - dumpMitigationBinaryStats(cfg); } diff --git a/dumpstate/dump_power.h b/dumpstate/dump_power.h deleted file mode 100644 index 4c83e8b..0000000 --- a/dumpstate/dump_power.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __DUMP_POWER_H -#define __DUMP_POWER_H - -#include "uapi/brownout_stats.h" - -/* BrownoutBinaryStatsConfig */ -#define NSEC_PER_SEC 1000000000L -#define DUMP_TIMES 12 -#define FVP_STATS_SIZE 4096 -#define UP_DOWN_LINK_SIZE 512 -#define STAT_NAME_SIZE 48 -#define STATS_MAX_SIZE 64 - -struct PmicSpecific { - const char *const OdpmDir; - const char *const OdpmEnabledRailsPath; - const char *const PmicNamePath; - const char *const PmicName; -}; - -struct numericStat { - char name[STAT_NAME_SIZE]; - int value; -}; - -struct BrownoutStatsExtend { - struct brownout_stats brownoutStats; - char fvpStats[FVP_STATS_SIZE]; - char pcieModem[UP_DOWN_LINK_SIZE]; - char pcieWifi[UP_DOWN_LINK_SIZE]; - struct numericStat numericStats[STATS_MAX_SIZE]; - timeval eventReceivedTime; - timeval dumpTime; - unsigned int eventIdx; -}; - -struct OdpmInstantPower { - struct timespec time; - double value; -}; - -struct BrownoutBinaryStatsConfig { - const char *const StoringPath; - const char *const BackupPath; - const char *const ThismealFileName; - const char *const LastmealFileName; - const std::vector pmic; -}; - -#endif /* __DUMP_POWER_H */ diff --git a/dumpstate/uapi/brownout_stats.h b/dumpstate/uapi/brownout_stats.h deleted file mode 100644 index b4085c0..0000000 --- a/dumpstate/uapi/brownout_stats.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __BROWNOUT_STATS_H -#define __BROWNOUT_STATS_H - -#define METER_CHANNEL_MAX 12 -#define DATA_LOGGING_LEN 20 -#define TRIGGERED_SOURCE_MAX 17 - -struct odpm_instant_data { - struct timespec time; - unsigned int value[METER_CHANNEL_MAX]; -}; - -/* Notice: sysfs only allocates a buffer of PAGE_SIZE - * so the sizeof brownout_stats should be smaller than that - */ -struct brownout_stats { - struct timespec triggered_time; - unsigned int triggered_idx; - - struct odpm_instant_data main_odpm_instant_data[DATA_LOGGING_LEN]; - struct odpm_instant_data sub_odpm_instant_data[DATA_LOGGING_LEN]; -}; -static_assert(sizeof(struct brownout_stats) <= PAGE_SIZE); - -#endif /* __BROWNOUT_STATS_H */