diff options
Diffstat (limited to 'test/thermal.c')
-rw-r--r-- | test/thermal.c | 659 |
1 files changed, 0 insertions, 659 deletions
diff --git a/test/thermal.c b/test/thermal.c deleted file mode 100644 index 1161ecbf1b..0000000000 --- a/test/thermal.c +++ /dev/null @@ -1,659 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Test thermal engine. - */ - -#include "common.h" -#include "console.h" -#include "driver/temp_sensor/thermistor.h" -#include "fan.h" -#include "hooks.h" -#include "host_command.h" -#include "printf.h" -#include "temp_sensor.h" -#include "test_util.h" -#include "thermal.h" -#include "timer.h" -#include "util.h" - - -/*****************************************************************************/ -/* Exported data */ - -struct ec_thermal_config thermal_params[TEMP_SENSOR_COUNT]; - -/* The tests below make some assumptions. */ -BUILD_ASSERT(TEMP_SENSOR_COUNT == 4); -BUILD_ASSERT(EC_TEMP_THRESH_COUNT == 3); - -/*****************************************************************************/ -/* Mock functions */ - -static int mock_temp[TEMP_SENSOR_COUNT]; -static int host_throttled; -static int cpu_throttled; -static int cpu_shutdown; -static int fan_pct; -static int no_temps_read; - -int mock_temp_get_val(int idx, int *temp_ptr) -{ - if (mock_temp[idx] >= 0) { - *temp_ptr = mock_temp[idx]; - return EC_SUCCESS; - } - - return EC_ERROR_NOT_POWERED; -} - -void chipset_force_shutdown(void) -{ - cpu_shutdown = 1; -} - -void chipset_throttle_cpu(int throttled) -{ - cpu_throttled = throttled; -} - -void host_throttle_cpu(int throttled) -{ - host_throttled = throttled; -} - -void fan_set_percent_needed(int fan, int pct) -{ - fan_pct = pct; -} - -void smi_sensor_failure_warning(void) -{ - no_temps_read = 1; -} - -/*****************************************************************************/ -/* Test utilities */ - -static void set_temps(int t0, int t1, int t2, int t3) -{ - mock_temp[0] = t0; - mock_temp[1] = t1; - mock_temp[2] = t2; - mock_temp[3] = t3; -} - -static void all_temps(int t) -{ - set_temps(t, t, t, t); -} - -static void reset_mocks(void) -{ - /* Ignore all sensors */ - memset(thermal_params, 0, sizeof(thermal_params)); - - /* All sensors report error anyway */ - set_temps(-1, -1 , -1, -1); - - /* Reset expectations */ - host_throttled = 0; - cpu_throttled = 0; - cpu_shutdown = 0; - fan_pct = 0; - no_temps_read = 0; -} - - -/*****************************************************************************/ -/* Tests */ - -static int test_init_val(void) -{ - reset_mocks(); - sleep(2); - - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - TEST_ASSERT(fan_pct == 0); - TEST_ASSERT(no_temps_read); - - sleep(2); - - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - TEST_ASSERT(fan_pct == 0); - TEST_ASSERT(no_temps_read); - - return EC_SUCCESS; -} - -static int test_sensors_can_be_read(void) -{ - reset_mocks(); - mock_temp[2] = 100; - - sleep(2); - - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - TEST_ASSERT(fan_pct == 0); - TEST_ASSERT(no_temps_read == 0); - - return EC_SUCCESS; -} - - -static int test_one_fan(void) -{ - reset_mocks(); - thermal_params[2].temp_fan_off = 100; - thermal_params[2].temp_fan_max = 200; - - all_temps(50); - sleep(2); - TEST_ASSERT(fan_pct == 0); - - all_temps(100); - sleep(2); - TEST_ASSERT(fan_pct == 0); - - all_temps(101); - sleep(2); - TEST_ASSERT(fan_pct == 1); - - all_temps(130); - sleep(2); - TEST_ASSERT(fan_pct == 30); - - all_temps(150); - sleep(2); - TEST_ASSERT(fan_pct == 50); - - all_temps(170); - sleep(2); - TEST_ASSERT(fan_pct == 70); - - all_temps(200); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - all_temps(300); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - return EC_SUCCESS; -} - -static int test_two_fans(void) -{ - reset_mocks(); - - thermal_params[1].temp_fan_off = 120; - thermal_params[1].temp_fan_max = 160; - thermal_params[2].temp_fan_off = 100; - thermal_params[2].temp_fan_max = 200; - - all_temps(50); - sleep(2); - TEST_ASSERT(fan_pct == 0); - - all_temps(100); - sleep(2); - TEST_ASSERT(fan_pct == 0); - - all_temps(101); - sleep(2); - TEST_ASSERT(fan_pct == 1); - - all_temps(130); - sleep(2); - /* fan 2 is still higher */ - TEST_ASSERT(fan_pct == 30); - - all_temps(150); - sleep(2); - /* now fan 1 is higher: 150 = 75% of [120-160] */ - TEST_ASSERT(fan_pct == 75); - - all_temps(170); - sleep(2); - /* fan 1 is maxed now */ - TEST_ASSERT(fan_pct == 100); - - all_temps(200); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - all_temps(300); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - return EC_SUCCESS; -} - -static int test_all_fans(void) -{ - reset_mocks(); - - thermal_params[0].temp_fan_off = 20; - thermal_params[0].temp_fan_max = 60; - thermal_params[1].temp_fan_off = 120; - thermal_params[1].temp_fan_max = 160; - thermal_params[2].temp_fan_off = 100; - thermal_params[2].temp_fan_max = 200; - thermal_params[3].temp_fan_off = 300; - thermal_params[3].temp_fan_max = 500; - - set_temps(1, 1, 1, 1); - sleep(2); - TEST_ASSERT(fan_pct == 0); - - /* Each sensor has its own range */ - set_temps(40, 0, 0, 0); - sleep(2); - TEST_ASSERT(fan_pct == 50); - - set_temps(0, 140, 0, 0); - sleep(2); - TEST_ASSERT(fan_pct == 50); - - set_temps(0, 0, 150, 0); - sleep(2); - TEST_ASSERT(fan_pct == 50); - - set_temps(0, 0, 0, 400); - sleep(2); - TEST_ASSERT(fan_pct == 50); - - set_temps(60, 0, 0, 0); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - set_temps(0, 160, 0, 0); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - set_temps(0, 0, 200, 0); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - set_temps(0, 0, 0, 500); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - /* But sensor 0 needs the most cooling */ - all_temps(20); - sleep(2); - TEST_ASSERT(fan_pct == 0); - - all_temps(21); - sleep(2); - TEST_ASSERT(fan_pct == 2); - - all_temps(30); - sleep(2); - TEST_ASSERT(fan_pct == 25); - - all_temps(40); - sleep(2); - TEST_ASSERT(fan_pct == 50); - - all_temps(50); - sleep(2); - TEST_ASSERT(fan_pct == 75); - - all_temps(60); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - all_temps(65); - sleep(2); - TEST_ASSERT(fan_pct == 100); - - return EC_SUCCESS; -} - -static int test_one_limit(void) -{ - reset_mocks(); - thermal_params[2].temp_host[EC_TEMP_THRESH_WARN] = 100; - thermal_params[2].temp_host[EC_TEMP_THRESH_HIGH] = 200; - thermal_params[2].temp_host[EC_TEMP_THRESH_HALT] = 300; - - all_temps(50); - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(100); - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(101); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(100); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(99); - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(199); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(200); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(201); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(200); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(199); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(99); - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(201); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(99); - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - all_temps(301); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - TEST_ASSERT(cpu_shutdown == 1); - - /* We probably won't be able to read the CPU temp while shutdown, - * so nothing will change. */ - all_temps(-1); - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - /* cpu_shutdown is only set for testing purposes. The thermal task - * doesn't do anything that could clear it. */ - - all_temps(50); - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - - return EC_SUCCESS; -} - -static int test_several_limits(void) -{ - reset_mocks(); - - thermal_params[1].temp_host[EC_TEMP_THRESH_WARN] = 150; - thermal_params[1].temp_host[EC_TEMP_THRESH_HIGH] = 200; - thermal_params[1].temp_host[EC_TEMP_THRESH_HALT] = 250; - - thermal_params[2].temp_host[EC_TEMP_THRESH_WARN] = 100; - thermal_params[2].temp_host[EC_TEMP_THRESH_HIGH] = 200; - thermal_params[2].temp_host[EC_TEMP_THRESH_HALT] = 300; - - thermal_params[3].temp_host[EC_TEMP_THRESH_WARN] = 20; - thermal_params[3].temp_host[EC_TEMP_THRESH_HIGH] = 30; - thermal_params[3].temp_host[EC_TEMP_THRESH_HALT] = 40; - - set_temps(500, 100, 150, 10); - sleep(2); - TEST_ASSERT(host_throttled == 1); /* 1=low, 2=warn, 3=low */ - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - set_temps(500, 50, -1, 10); /* 1=low, 2=X, 3=low */ - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - TEST_ASSERT(cpu_shutdown == 0); - - set_temps(500, 170, 210, 10); /* 1=warn, 2=high, 3=low */ - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - TEST_ASSERT(cpu_shutdown == 0); - - set_temps(500, 100, 50, 40); /* 1=low, 2=low, 3=high */ - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - TEST_ASSERT(cpu_shutdown == 0); - - set_temps(500, 100, 50, 41); /* 1=low, 2=low, 3=shutdown */ - sleep(2); - TEST_ASSERT(host_throttled == 1); - TEST_ASSERT(cpu_throttled == 1); - TEST_ASSERT(cpu_shutdown == 1); - - all_temps(0); /* reset from shutdown */ - sleep(2); - TEST_ASSERT(host_throttled == 0); - TEST_ASSERT(cpu_throttled == 0); - - - return EC_SUCCESS; -} - -/* Tests for ncp15wb thermistor ADC-to-temp calculation */ -#define LOW_ADC_TEST_VALUE 887 /* 0 C */ -#define HIGH_ADC_TEST_VALUE 100 /* > 100C */ - -static int test_ncp15wb_adc_to_temp(void) -{ - int i; - uint8_t temp; - uint8_t new_temp; - - /* ADC value to temperature table, data from datasheet */ - struct { - int adc; - int temp; - } adc_temp_datapoints[] = { - { 615, 30 }, - { 561, 35 }, - { 508, 40 }, - { 407, 50 }, - { 315, 60 }, - { 243, 70 }, - { 186, 80 }, - { 140, 90 }, - { 107, 100 }, - }; - - - /* - * Verify that calculated temp is decreasing for entire ADC range, - * and that a tick down in ADC value results in no more than 1C - * decrease. - */ - i = LOW_ADC_TEST_VALUE; - temp = ncp15wb_calculate_temp(i); - - while (--i > HIGH_ADC_TEST_VALUE) { - new_temp = ncp15wb_calculate_temp(i); - TEST_ASSERT(new_temp == temp || - new_temp == temp + 1); - temp = new_temp; - } - - /* Verify several datapoints are within 1C accuracy */ - for (i = 0; i < ARRAY_SIZE(adc_temp_datapoints); ++i) { - temp = ncp15wb_calculate_temp(adc_temp_datapoints[i].adc); - ASSERT(temp >= adc_temp_datapoints[i].temp - 1 && - temp <= adc_temp_datapoints[i].temp + 1); - } - - return EC_SUCCESS; -} - -#define THERMISTOR_SCALING_FACTOR 13 -static int test_thermistor_linear_interpolate(void) -{ - int i, t, t0; - uint16_t mv; - /* Simple test case - a straight line. */ - struct thermistor_data_pair line_data[] = { - { 100, 0 }, { 0, 100 } - }; - struct thermistor_info line_info = { - .scaling_factor = 1, - .num_pairs = ARRAY_SIZE(line_data), - .data = line_data, - }; - /* - * Modelled test case - Data derived from Seinhart-Hart equation in a - * resistor divider circuit with Vdd=3300mV, R = 51.1Kohm, and Murata - * NCP15WB-series thermistor (B = 4050, T0 = 298.15, nominal - * resistance (R0) = 47Kohm). - */ - struct thermistor_data_pair data[] = { - { 2512 / THERMISTOR_SCALING_FACTOR, 0 }, - { 2158 / THERMISTOR_SCALING_FACTOR, 10 }, - { 1772 / THERMISTOR_SCALING_FACTOR, 20 }, - { 1398 / THERMISTOR_SCALING_FACTOR, 30 }, - { 1070 / THERMISTOR_SCALING_FACTOR, 40 }, - { 803 / THERMISTOR_SCALING_FACTOR, 50 }, - { 597 / THERMISTOR_SCALING_FACTOR, 60 }, - { 443 / THERMISTOR_SCALING_FACTOR, 70 }, - { 329 / THERMISTOR_SCALING_FACTOR, 80 }, - { 247 / THERMISTOR_SCALING_FACTOR, 90 }, - { 188 / THERMISTOR_SCALING_FACTOR, 100 }, - }; - struct thermistor_info info = { - .scaling_factor = THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(data), - .data = data, - }; - /* - * Reference data points to compare accuracy, taken from same set - * of derived values but at temp - 1, temp + 1, and in between. - */ - struct { - uint16_t mv; /* not scaled */ - int temp; - } cmp[] = { - { 3030, 1 }, { 2341, 5 }, { 2195, 9 }, - { 2120, 11 }, { 1966, 15 }, { 1811, 19 }, - { 1733, 21 }, { 1581, 25 }, { 1434, 29 }, - { 1363, 31 }, { 1227, 35 }, { 1100, 39 }, - { 1040, 41 }, { 929, 45 }, { 827, 49 }, - { 780, 51 }, { 693, 55 }, { 615, 59 }, - { 579, 61 }, { 514, 65 }, { 460, 69 }, - { 430, 71 }, { 382, 75 }, { 339, 79 }, - { 320, 81 }, { 285, 85 }, { 254, 89 }, - { 240, 91 }, { 214, 95 }, { 192, 99 }, - }; - - /* Return lowest temperature in data set if voltage is too high. */ - mv = (data[0].mv * info.scaling_factor) + 1; - t = thermistor_linear_interpolate(mv, &info); - TEST_ASSERT(t == data[0].temp); - - /* Return highest temperature in data set if voltage is too low. */ - mv = (data[info.num_pairs - 1].mv * info.scaling_factor) - 1; - t = thermistor_linear_interpolate(mv, &info); - TEST_ASSERT(t == data[info.num_pairs - 1].temp); - - /* Simple line test */ - for (mv = line_data[0].mv; - mv > line_data[line_info.num_pairs - 1].mv; - mv--) { - t = thermistor_linear_interpolate(mv, &line_info); - TEST_ASSERT(mv == line_data[line_info.num_pairs - 1].temp - t); - } - - /* - * Verify that calculated temperature monotonically - * decreases with increase in voltage (0-5V, 10mV steps). - */ - for (mv = data[0].mv * info.scaling_factor, t0 = data[0].temp; - mv > data[info.num_pairs - 1].mv; - mv -= 10) { - int t1 = thermistor_linear_interpolate(mv, &info); - - TEST_ASSERT(t1 >= t0); - t0 = t1; - } - - /* Verify against modelled data, +/- 1C due to scaling. */ - for (i = 0; i < info.num_pairs; i++) { - mv = data[i].mv * info.scaling_factor; - - t = thermistor_linear_interpolate(mv, &info); - TEST_ASSERT(t >= data[i].temp - 1 && t <= data[i].temp + 1); - } - - /* - * Verify data points that are interpolated by algorithm, allowing - * 1C of inaccuracy. - */ - for (i = 0; i < ARRAY_SIZE(cmp); i++) { - t = thermistor_linear_interpolate(cmp[i].mv, &info); - TEST_ASSERT(t >= cmp[i].temp - 1 && t <= cmp[i].temp + 1); - } - - return EC_SUCCESS; -} - -void run_test(int argc, char **argv) -{ - RUN_TEST(test_init_val); - RUN_TEST(test_sensors_can_be_read); - RUN_TEST(test_one_fan); - RUN_TEST(test_two_fans); - RUN_TEST(test_all_fans); - - RUN_TEST(test_one_limit); - RUN_TEST(test_several_limits); - - RUN_TEST(test_ncp15wb_adc_to_temp); - RUN_TEST(test_thermistor_linear_interpolate); - test_print_result(); -} |