1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 #include <errno.h> 5 #include <string.h> 6 7 #include <rte_log.h> 8 9 #include "rte_power_guest_channel.h" 10 #include "guest_channel.h" 11 #include "power_kvm_vm.h" 12 13 #define FD_PATH "/dev/virtio-ports/virtio.serial.port.poweragent" 14 15 static struct rte_power_channel_packet pkt[RTE_MAX_LCORE]; 16 17 int 18 power_kvm_vm_check_supported(void) 19 { 20 return guest_channel_host_check_exists(FD_PATH); 21 } 22 23 int 24 power_kvm_vm_init(unsigned int lcore_id) 25 { 26 if (lcore_id >= RTE_MAX_LCORE) { 27 RTE_LOG(ERR, POWER, "Core(%u) is out of range 0...%d\n", 28 lcore_id, RTE_MAX_LCORE-1); 29 return -1; 30 } 31 pkt[lcore_id].command = RTE_POWER_CPU_POWER; 32 pkt[lcore_id].resource_id = lcore_id; 33 return guest_channel_host_connect(FD_PATH, lcore_id); 34 } 35 36 int 37 power_kvm_vm_exit(unsigned int lcore_id) 38 { 39 guest_channel_host_disconnect(lcore_id); 40 return 0; 41 } 42 43 uint32_t 44 power_kvm_vm_freqs(__rte_unused unsigned int lcore_id, 45 __rte_unused uint32_t *freqs, 46 __rte_unused uint32_t num) 47 { 48 RTE_LOG(ERR, POWER, "rte_power_freqs is not implemented " 49 "for Virtual Machine Power Management\n"); 50 return -ENOTSUP; 51 } 52 53 uint32_t 54 power_kvm_vm_get_freq(__rte_unused unsigned int lcore_id) 55 { 56 RTE_LOG(ERR, POWER, "rte_power_get_freq is not implemented " 57 "for Virtual Machine Power Management\n"); 58 return -ENOTSUP; 59 } 60 61 int 62 power_kvm_vm_set_freq(__rte_unused unsigned int lcore_id, 63 __rte_unused uint32_t index) 64 { 65 RTE_LOG(ERR, POWER, "rte_power_set_freq is not implemented " 66 "for Virtual Machine Power Management\n"); 67 return -ENOTSUP; 68 } 69 70 static inline int 71 send_msg(unsigned int lcore_id, uint32_t scale_direction) 72 { 73 int ret; 74 75 if (lcore_id >= RTE_MAX_LCORE) { 76 RTE_LOG(ERR, POWER, "Core(%u) is out of range 0...%d\n", 77 lcore_id, RTE_MAX_LCORE-1); 78 return -1; 79 } 80 pkt[lcore_id].unit = scale_direction; 81 ret = guest_channel_send_msg(&pkt[lcore_id], lcore_id); 82 if (ret == 0) 83 return 1; 84 RTE_LOG(DEBUG, POWER, "Error sending message: %s\n", 85 ret > 0 ? strerror(ret) : "channel not connected"); 86 return -1; 87 } 88 89 int 90 power_kvm_vm_freq_up(unsigned int lcore_id) 91 { 92 return send_msg(lcore_id, RTE_POWER_SCALE_UP); 93 } 94 95 int 96 power_kvm_vm_freq_down(unsigned int lcore_id) 97 { 98 return send_msg(lcore_id, RTE_POWER_SCALE_DOWN); 99 } 100 101 int 102 power_kvm_vm_freq_max(unsigned int lcore_id) 103 { 104 return send_msg(lcore_id, RTE_POWER_SCALE_MAX); 105 } 106 107 int 108 power_kvm_vm_freq_min(unsigned int lcore_id) 109 { 110 return send_msg(lcore_id, RTE_POWER_SCALE_MIN); 111 } 112 113 int 114 power_kvm_vm_turbo_status(__rte_unused unsigned int lcore_id) 115 { 116 RTE_LOG(ERR, POWER, "rte_power_turbo_status is not implemented for Virtual Machine Power Management\n"); 117 return -ENOTSUP; 118 } 119 120 int 121 power_kvm_vm_enable_turbo(unsigned int lcore_id) 122 { 123 return send_msg(lcore_id, RTE_POWER_ENABLE_TURBO); 124 } 125 126 int 127 power_kvm_vm_disable_turbo(unsigned int lcore_id) 128 { 129 return send_msg(lcore_id, RTE_POWER_DISABLE_TURBO); 130 } 131 132 struct rte_power_core_capabilities; 133 int power_kvm_vm_get_capabilities(__rte_unused unsigned int lcore_id, 134 __rte_unused struct rte_power_core_capabilities *caps) 135 { 136 RTE_LOG(ERR, POWER, "rte_power_get_capabilities is not implemented for Virtual Machine Power Management\n"); 137 return -ENOTSUP; 138 } 139