Commit 5d9ddfa1 authored by Raptor Engineering Development Team's avatar Raptor Engineering Development Team
Browse files

Add background temperature monitoring daemon

This enables temperature display in the Web portal,
and lays the groundwork for a future fan control
service.
parent 4458da8d
......@@ -139,9 +139,11 @@ uint8_t kestrel_basic_init_complete = 0;
// Thread identifiers
k_tid_t kestrel_service_thread_id = NULL;
k_tid_t kestrel_console_thread_id = NULL;
k_tid_t thermal_service_thread_id = NULL;
// Mutexes
struct k_mutex vuart1_access_mutex;
struct k_mutex occ_access_mutex;
// Console structures
const struct shell *host_console_service_task_shell = NULL;
......@@ -1737,6 +1739,13 @@ static int process_interrupts_stage2(void)
uint8_t led_post_code = (((post_code >> 8) & 0xf) << 4) | (post_code & 0xf);
set_led_bank_display(led_post_code);
if (post_code == 0xfefe)
{
host_power_status = HOST_POWER_STATUS_RUNNING;
set_led_bank_display(0);
display_character('0' + 2 + host_power_status, 0); // STATUS CODE
}
if (enable_post_code_console_output)
{
KESTREL_LOG("[POST CODE] %d.%d", (post_code >> 8) & 0xff, post_code & 0xff);
......@@ -2183,6 +2192,7 @@ static int disable_avsbus_pmbus(const cpu_info_t *cpu_info, int cpu_count)
void power_off_chassis(void)
{
host_power_status = HOST_POWER_STATUS_POWERING_OFF;
display_character('0' + 2 + host_power_status, 0); // STATUS CODE
// Disable PMBUS
if (disable_avsbus_pmbus(g_cpu_info, configured_cpu_count))
......@@ -2196,6 +2206,7 @@ void power_off_chassis(void)
run_post_shutdown_bmc_peripheral_teardown();
host_power_status = HOST_POWER_STATUS_OFFLINE;
display_character('0' + 2 + host_power_status, 0); // STATUS CODE
}
static int power_on_chassis(void)
......@@ -2207,12 +2218,14 @@ static int power_on_chassis(void)
uint8_t byte;
host_power_status = HOST_POWER_STATUS_POWERING_ON;
display_character('0' + 2 + host_power_status, 0); // STATUS CODE
// Verify communication with platform control FPGA
platform_fpga_identifier[0] = i2c_read_register_byte((uint8_t *)I2CMASTER4_BASE, HOST_PLATFORM_FPGA_I2C_ADDRESS, 0x0c, NULL);
if (platform_fpga_identifier[0] == 0xff)
{
host_power_status = HOST_POWER_STATUS_OFFLINE;
display_character('0' + 2 + host_power_status, 0); // STATUS CODE
return -1;
}
platform_fpga_identifier[1] = i2c_read_register_byte((uint8_t *)I2CMASTER4_BASE, HOST_PLATFORM_FPGA_I2C_ADDRESS, 0x0d, NULL);
......@@ -2222,6 +2235,7 @@ static int power_on_chassis(void)
(platform_fpga_identifier[3] != 0x20))
{
host_power_status = HOST_POWER_STATUS_OFFLINE;
display_character('0' + 2 + host_power_status, 0); // STATUS CODE
return -1;
}
KESTREL_LOG("Platform FPGA communication verified");
......@@ -2280,7 +2294,8 @@ static int power_on_chassis(void)
return -5;
}
host_power_status = HOST_POWER_STATUS_RUNNING;
host_power_status = HOST_POWER_STATUS_IPLING;
display_character('0' + 2 + host_power_status, 0); // STATUS CODE
return 0;
}
......@@ -3447,6 +3462,7 @@ int kestrel_init(void)
#if (WITH_ZEPHYR)
// Initialize mutexes
k_mutex_init(&vuart1_access_mutex);
k_mutex_init(&occ_access_mutex);
#endif
for (int i = 0; i < MAX_CPUS_SUPPORTED; i++)
......
......@@ -30,8 +30,9 @@
#define HOST_POWER_STATUS_OFFLINE 0
#define HOST_POWER_STATUS_POWERING_ON 1
#define HOST_POWER_STATUS_RUNNING 2
#define HOST_POWER_STATUS_POWERING_OFF 3
#define HOST_POWER_STATUS_IPLING 2
#define HOST_POWER_STATUS_RUNNING 3
#define HOST_POWER_STATUS_POWERING_OFF 4
#define KESTREL_VERSION_MAJOR 0
#define KESTREL_VERSION_MINOR 1
......@@ -56,6 +57,8 @@ extern uint8_t host_power_status;
#if (WITH_ZEPHYR)
extern k_tid_t kestrel_service_thread_id;
extern k_tid_t kestrel_console_thread_id;
extern k_tid_t thermal_service_thread_id;
extern struct k_mutex occ_access_mutex;
extern const struct shell *host_console_service_task_shell;
#endif
......
......@@ -233,6 +233,11 @@ static int kestrel_shell_cmd_occcontrol(const struct shell *shell, size_t argc,
}
if (strcmp(argv[1], "poll") == 0) {
if (k_mutex_lock(&occ_access_mutex, K_MSEC(1000)) != 0) {
printk("Unable to acquire OCC mutex in a timely manner! %s:%d\n", __FILE__, __LINE__);
return -EAGAIN;
}
if (occ_poll(0, 0x2400, IBM_POWER9_SBE_OCC_RESPONSE_SIZE, response_data, &response_length))
{
shell_print(shell, "OCC not responding!");
......@@ -249,6 +254,13 @@ static int kestrel_shell_cmd_occcontrol(const struct shell *shell, size_t argc,
shell_print(shell, "Temperature sensor 0x%08x: %d° C", host_cpu_temperature_sensor_data[sensor_number].sensor_id, host_cpu_temperature_sensor_data[sensor_number].temperature_c);
}
}
k_mutex_unlock(&occ_access_mutex);
}
else {
shell_print(shell, "%s: Invalid parameter", argv[0]);
print_kestrel_occcontrol_command_usage(shell, argv[0]);
return -1;
}
return 0;
......
......@@ -12,6 +12,7 @@ LOG_MODULE_REGISTER(webportal, LOG_LEVEL_DBG);
#include <data/json.h>
#include "simple_pwm.h"
#include "sbe_fsi.h"
#include "webportal.h"
#include "redfish.h"
......@@ -160,6 +161,9 @@ const char* host_power_status_to_string(int power_status)
else if (power_status == HOST_POWER_STATUS_POWERING_ON) {
return "Powering On";
}
else if (power_status == HOST_POWER_STATUS_IPLING) {
return "Initial Program Load";
}
else if (power_status == HOST_POWER_STATUS_RUNNING) {
return "Online";
}
......@@ -201,6 +205,17 @@ int host_status_handler(struct mg_connection *conn, void *cbdata)
mg_printf(conn, "PWM channel %d - %d%% (%d RPM)<br>\n", i, (pwm_values[i] * 100) / 256, tach_values[i]);
}
mg_printf(conn, "</div>");
if (host_cpu_temperature_sensor_count != 0)
{
mg_printf(conn, "<p>");
mg_printf(conn, "<b>Thermal</b><br>");
mg_printf(conn, "<div style=\"margin-left: 20px\">");
for (i = 0; i < host_cpu_temperature_sensor_count; i++)
{
mg_printf(conn, "Sensor 0x%08x: %d° C<br>\n", host_cpu_temperature_sensor_data[i].sensor_id, host_cpu_temperature_sensor_data[i].temperature_c);
}
mg_printf(conn, "</div>");
}
mg_printf(conn, "<p>");
mg_printf(conn, "<b>Control</b><br>");
mg_printf(conn, "<div style=\"margin-left: 20px\">");
......
......@@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(kestrel_init, LOG_LEVEL_DBG);
#include "webservice.h"
#include "flash_filesystem.h"
#include "sbe_fsi.h"
#include "kestrel.h"
static struct gpio_callback host_power_button_callback_data;
......@@ -30,6 +31,9 @@ static struct k_sem kestrel_init_thread_lock;
static K_THREAD_STACK_DEFINE(kestrel_service_thread_stack, 16384);
static struct k_thread kestrel_service_thread_data;
static K_THREAD_STACK_DEFINE(thermal_service_thread_stack, 16384);
static struct k_thread thermal_service_thread_data;
#define KESTREL_IDLE_THREAD_PRIORITY K_PRIO_PREEMPT(CONFIG_NUM_PREEMPT_PRIORITIES - 1)
#define BUTTON_PRESS_DEBOUNCE_DELAY_MS 200
......@@ -60,6 +64,37 @@ static void kestrel_service_thread(void)
}
}
static void thermal_service_thread(void)
{
uint8_t response_data[IBM_POWER9_SBE_OCC_RESPONSE_SIZE];
size_t response_length = 0;
while (1) {
if (host_power_status == HOST_POWER_STATUS_RUNNING)
{
if (k_mutex_lock(&occ_access_mutex, K_MSEC(1000)) != 0) {
printk("Unable to acquire OCC mutex in a timely manner! %s:%d\n", __FILE__, __LINE__);
continue;
}
if (occ_poll(0, 0x2400, IBM_POWER9_SBE_OCC_RESPONSE_SIZE, response_data, &response_length))
{
// Unable to read sensors
host_cpu_temperature_sensor_count = 0;
}
k_mutex_unlock(&occ_access_mutex);
k_usleep(100000);
}
else
{
host_cpu_temperature_sensor_count = 0;
k_usleep(100000);
}
}
}
void host_power_button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
static uint64_t last_press = 0;
......@@ -197,6 +232,12 @@ void main(void)
NULL, NULL, NULL, KESTREL_SERVICE_THREAD_PRIORITY, 0, K_NO_WAIT);
k_thread_name_set(kestrel_service_thread_id, "kestrel_service");
thermal_service_thread_id = k_thread_create(&thermal_service_thread_data, thermal_service_thread_stack,
K_THREAD_STACK_SIZEOF(thermal_service_thread_stack),
(k_thread_entry_t)thermal_service_thread,
NULL, NULL, NULL, KESTREL_SERVICE_THREAD_PRIORITY, 0, K_NO_WAIT);
k_thread_name_set(thermal_service_thread_id, "thermal_service");
// Run late setup
configure_gpios();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment