diff --git a/chip/lm4/mock_lpc.c b/chip/lm4/mock_lpc.c new file mode 100644 index 0000000000..52495bc9c9 --- /dev/null +++ b/chip/lm4/mock_lpc.c @@ -0,0 +1,63 @@ +/* Copyright (c) 2012 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. + */ + +/* Mock LPC module for Chrome EC */ + +#include "board.h" +#include "lpc.h" +#include "registers.h" +#include "uart.h" + +void lpc_set_host_events(uint32_t mask) +{ + uart_printf("Host event: %x\n", mask); +} + + +uint32_t lpc_get_host_events(void) +{ + /* Not implemented */ + return 0; +} + + +void lpc_clear_host_events(uint32_t mask) +{ + uart_printf("Clear host event: %x\n", mask); +} + + +void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask) +{ + uart_printf("Set host event mask: type %d = %x\n", type, mask); +} + + +uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type) +{ + /* Not implemented */ + return 0; +} + + +int lpc_comx_has_char(void) +{ + /* Not implemented */ + return 0; +} + + +int lpc_comx_get_char(void) +{ + /* Not implemented */ + return 0; +} + + +void lpc_comx_put_char(int c) +{ + /* Not implemented */ + return; +} diff --git a/chip/lm4/mock_pwm.c b/chip/lm4/mock_pwm.c new file mode 100644 index 0000000000..7bd356a6a9 --- /dev/null +++ b/chip/lm4/mock_pwm.c @@ -0,0 +1,55 @@ +/* Copyright (c) 2012 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. + */ + +/* Mock PWM control module for Chrome EC */ + +#include "pwm.h" +#include "timer.h" +#include "uart.h" + +static int fan_target_rpm; +static int kblight; + +int pwm_set_fan_target_rpm(int rpm) +{ + uart_printf("Fan RPM: %d\n", rpm); + fan_target_rpm = rpm; + return EC_SUCCESS; +} + + +int pwm_get_fan_target_rpm(void) +{ + return fan_target_rpm; +} + + +int pwm_set_keyboard_backlight(int percent) +{ + uart_printf("KBLight: %d\n", percent); + kblight = percent; + return EC_SUCCESS; +} + + +int pwm_get_keyboard_backlight(void) +{ + return kblight; +} + + +int pwm_get_keyboard_backlight_enabled(void) +{ + /* Always enabled */ + return 1; +} + + +void pwm_task(void) +{ + /* Do nothing */ + while (1) + usleep(5000000); +} diff --git a/common/mock_temp_sensor.c b/common/mock_temp_sensor.c new file mode 100644 index 0000000000..7f2a6b1dd9 --- /dev/null +++ b/common/mock_temp_sensor.c @@ -0,0 +1,81 @@ +/* Copyright (c) 2012 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. + */ + +/* Mock temperature sensor module for Chrome EC */ + +#include "board.h" +#include "console.h" +#include "temp_sensor.h" +#include "timer.h" +#include "util.h" + +/* Defined in board_temp_sensor.c. Must be in the same order as + * in enum temp_sensor_id. + */ +extern const struct temp_sensor_t temp_sensors[TEMP_SENSOR_COUNT]; + +static int temp_val[TEMP_SENSOR_TYPE_COUNT]; + +int temp_sensor_powered(enum temp_sensor_id id) +{ + /* Always powered */ + return 1; +} + + +int temp_sensor_read(enum temp_sensor_id id) +{ + return temp_val[temp_sensors[id].type]; +} + + +void temp_sensor_task(void) +{ + /* Do nothing */ + while (1) + usleep(5000000); +} + + +static int command_set_temp(int argc, char **argv, int type) +{ + char *e; + int t; + + ASSERT(argc == 2); + t = strtoi(argv[1], &e, 0); + temp_val[type] = t; + return EC_SUCCESS; +} + + +static int command_set_cpu_temp(int argc, char **argv) +{ + return command_set_temp(argc, argv, TEMP_SENSOR_TYPE_CPU); +} +DECLARE_CONSOLE_COMMAND(setcputemp, command_set_cpu_temp, + "value", + "Set mock CPU temperature value", + NULL); + + +static int command_set_board_temp(int argc, char **argv) +{ + return command_set_temp(argc, argv, TEMP_SENSOR_TYPE_BOARD); +} +DECLARE_CONSOLE_COMMAND(setboardtemp, command_set_board_temp, + "value", + "Set mock board temperature value", + NULL); + + +static int command_set_case_temp(int argc, char **argv) +{ + return command_set_temp(argc, argv, TEMP_SENSOR_TYPE_CASE); +} +DECLARE_CONSOLE_COMMAND(setcasetemp, command_set_case_temp, + "value", + "Set mock case temperature value", + NULL); diff --git a/common/mock_x86_power.c b/common/mock_x86_power.c new file mode 100644 index 0000000000..4842044382 --- /dev/null +++ b/common/mock_x86_power.c @@ -0,0 +1,60 @@ +/* Copyright (c) 2012 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. + */ + +/* Mock X86 chipset power control module for Chrome EC */ + +#include "chipset.h" +#include "lpc.h" +#include "timer.h" +#include "uart.h" +#include "x86_power.h" + +void x86_power_cpu_overheated(int too_hot) +{ + /* Print transitions */ + static int last_val = 0; + if (too_hot != last_val) { + if (too_hot) + uart_printf("CPU overheated.\n"); + else + uart_printf("CPU no longer overheated.\n"); + last_val = too_hot; + } +} + + +void x86_power_force_shutdown(void) +{ + uart_puts("Force shutdown\n"); +} + + +void chipset_throttle_cpu(int throttle) +{ + /* Print transitions */ + static int last_val = 0; + if (throttle != last_val) { + if (throttle) + uart_printf("Throttle CPU.\n"); + else + uart_printf("No longer throttle CPU.\n"); + last_val = throttle; + } +} + + +void x86_power_interrupt(enum gpio_signal signal) +{ + /* Not implemented */ + return; +} + + +void x86_power_task(void) +{ + /* Do nothing */ + while (1) + usleep(5000000); +} diff --git a/test/build.mk b/test/build.mk index 5966f41579..2ad8df6c4f 100644 --- a/test/build.mk +++ b/test/build.mk @@ -6,7 +6,7 @@ # on-board test binaries build # -test-list=hello pingpong timer_calib timer_dos timer_jump mutex +test-list=hello pingpong timer_calib timer_dos timer_jump mutex thermal #disable: powerdemo pingpong-y=pingpong.o @@ -14,3 +14,9 @@ powerdemo-y=powerdemo.o timer_calib-y=timer_calib.o timer_dos-y=timer_dos.o mutex-y=mutex.o + +# Mock modules for 'thermal' +chip-mock-thermal-lpc.o=mock_lpc.o +chip-mock-thermal-pwm.o=mock_pwm.o +common-mock-thermal-x86_power.o=mock_x86_power.o +common-mock-thermal-temp_sensor.o=mock_temp_sensor.o diff --git a/test/thermal.py b/test/thermal.py new file mode 100644 index 0000000000..30090b6b74 --- /dev/null +++ b/test/thermal.py @@ -0,0 +1,100 @@ +# Copyright (c) 2012 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. +# +# Thermal engine unit test +# + +CPU = 0 +BOARD = 1 +CASE = 2 + +def getWarningConfig(helper, sensor_type): + ret = dict() + helper.ec_command("thermalconf %d" % sensor_type) + ret['warning'] = int(helper.wait_output( + "Warning:\s*(?P\d+) K", use_re=True)["t"]) + ret['cpudown'] = int(helper.wait_output( + "CPU Down:\s*(?P\d+) K", use_re=True)["t"]) + ret['powerdown'] = int(helper.wait_output( + "Power Down:\s*(?P\d+) K", use_re=True)["t"]) + return ret + +def getFanConfig(helper, sensor_type): + ret = list() + helper.ec_command("thermalfan %d" % sensor_type) + while True: + try: + match = helper.wait_output("(?P\d+)\s*K:\s*(?P-?\d+)\s", + use_re=True, timeout=1) + ret.append((int(match["t"]), int(match["r"]))) + except: + break + return ret + + +def test(helper): + helper.wait_output("Inits done") + + # Get thermal engine configuration + config = [getWarningConfig(helper, sensor_type) + for sensor_type in xrange(3)] + fan_config = [getFanConfig(helper, sensor_type) + for sensor_type in xrange(3)] + + # Set initial temperature values + helper.ec_command("setcputemp %d" % max(fan_config[CPU][0][0]-1, 0)) + helper.ec_command("setboardtemp %d" % max(fan_config[BOARD][0][0]-1, 0)) + helper.ec_command("setcasetemp %d" % max(fan_config[CASE][0][0]-1, 0)) + + # Increase CPU temperature to first fan step + # Check if fan comes up + helper.ec_command("setcputemp %d" % fan_config[CPU][0][0]) + helper.wait_output("Fan RPM: %d" % fan_config[CPU][0][1], timeout=11) + + # Increase CPU temperature to second fan step + helper.ec_command("setcputemp %d" % fan_config[CPU][1][0]) + helper.wait_output("Fan RPM: %d" % fan_config[CPU][1][1], timeout=11) + + # Lower CPU temperature to 1 degree below second fan step + # Check fan speed doesn't change + helper.ec_command("setcputemp %d" % (fan_config[CPU][1][0]-1)) + for i in xrange(12): + helper.wait_output("Fan RPM: %d" % fan_config[CPU][1][1], timeout=2) + + # Set CPU temperature to a high value for only one second + # Check fan speed doesn't change + helper.ec_command("setcputemp 400") + helper.wait_output("Fan RPM: %d" % fan_config[CPU][1][1]) + helper.ec_command("setcputemp %d" % fan_config[CPU][1][0]) + + # Set case temperature to first fan step + # Check fan is set to second step + helper.ec_command("setcasetemp %d" % fan_config[CASE][0][0]) + for i in xrange(12): + helper.wait_output("Fan RPM: %d" % fan_config[CASE][1][1], timeout=2) + + # Set case temperature to third fan step + # Check fan is set to third step + helper.ec_command("setcasetemp %d" % fan_config[CASE][2][0]) + helper.wait_output("Fan RPM: %d" % fan_config[CASE][2][1], timeout=11) + + # Set CPU temperature to trigger warning and throttle CPU + helper.ec_command("setcputemp %d" % config[CPU]['warning']) + helper.wait_output("Throttle CPU.", timeout=11) + helper.wait_output("Host event: 200", timeout=2) + + # Lower CPU temperature and check CPU is not throttled + helper.ec_command("setcputemp %d" % (config[CPU]['warning']-5)) + helper.wait_output("No longer throttle CPU.", timeout=2) + + # Set CPU temperature to trigger CPU shutdown + helper.ec_command("setcputemp %d" % config[CPU]['cpudown']) + helper.wait_output("CPU overheated", timeout=11) + + # Set CPU temperature to trigger force shutdown + helper.ec_command("setcputemp %d" % config[CPU]['powerdown']) + helper.wait_output("Force shutdown", timeout=11) + + # Pass! + return True diff --git a/test/thermal.tasklist b/test/thermal.tasklist new file mode 100644 index 0000000000..87f1d0d302 --- /dev/null +++ b/test/thermal.tasklist @@ -0,0 +1,22 @@ +/* Copyright (c) 2012 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. + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK(n, r, d) where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + */ +#define CONFIG_TASK_LIST \ + TASK(WATCHDOG, watchdog_task, NULL) \ + TASK(TEMPSENSOR, temp_sensor_task, NULL) \ + TASK(THERMAL, thermal_task, NULL) \ + TASK(PWM, pwm_task, NULL) \ + TASK(X86POWER, x86_power_task, NULL) \ + TASK(CONSOLE, console_task, NULL)