Revert "bcl: add parser for thismeal.bin and lastmeal.bin"

This reverts commit fa0ee1521c.

Reason for revert: migrate binary parser to battery_mitigation

Change-Id: I7c97c3cb91924cdc19f61c8b7ea85e6c49813c42
This commit is contained in:
Sam Ou 2023-10-31 16:56:22 +00:00 committed by samou
parent 50751f0529
commit ce8c8e9bb8
3 changed files with 1 additions and 487 deletions

View file

@ -14,8 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
#include <algorithm>
#include <cmath>
#include <cstring> #include <cstring>
#include <dirent.h> #include <dirent.h>
#include <dump/pixel_dump.h> #include <dump/pixel_dump.h>
@ -25,13 +23,11 @@
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <time.h> #include <time.h>
#include <vector> #include <vector>
#include <sys/mman.h>
#include <sys/stat.h>
#include <android-base/file.h> #include <android-base/file.h>
#include <android-base/strings.h> #include <android-base/strings.h>
#include "DumpstateUtil.h" #include "DumpstateUtil.h"
#include "dump_power.h"
void printTitle(const char *msg) { void printTitle(const char *msg) {
printf("\n------ %s ------\n", 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<odpm_instant_data> &odpmData,
double *lpfBitResolutions, char **lpfChannelNames) {
std::vector<timespec> validTime;
std::vector<OdpmInstantPower> instPower[METER_CHANNEL_MAX];
std::vector<OdpmInstantPower> instPowerMax;
std::vector<OdpmInstantPower> instPowerMin;
std::vector<double> instPowerList;
std::vector<double> 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<odpm_instant_data> 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() { void dumpMitigationStats() {
int ret; int ret;
const char *directory = "/sys/devices/virtual/pmic/mitigation/last_triggered_count/"; const char *directory = "/sys/devices/virtual/pmic/mitigation/last_triggered_count/";
@ -1278,29 +909,6 @@ void dumpIrqDurationCounts() {
} }
int main() { 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(); dumpPowerStatsTimes();
dumpAcpmStats(); dumpAcpmStats();
dumpPowerSupplyStats(); dumpPowerSupplyStats();
@ -1320,6 +928,5 @@ int main() {
dumpMitigationStats(); dumpMitigationStats();
dumpMitigationDirs(); dumpMitigationDirs();
dumpIrqDurationCounts(); dumpIrqDurationCounts();
dumpMitigationBinaryStats(cfg);
} }

View file

@ -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<PmicSpecific> pmic;
};
#endif /* __DUMP_POWER_H */

View file

@ -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 */