/* * Check the return code for H_HTM hcall. * Return non-zero value (1) if either H_PARTIAL or H_SUCCESS * is returned. For other return codes: * Return zero if H_NOT_AVAILABLE. * Return -EBUSY if hcall return busy. * Return -EINVAL if any parameter or operation is not valid. * Return -EPERM if HTM Virtualization Engine Technology code * is not applied. * Return -EIO if the HTM state is not valid.
*/ static ssize_t htm_return_check(long rc)
{ switch (rc) { case H_SUCCESS: /* H_PARTIAL for the case where all available data can't be * returned due to buffer size constraint.
*/ case H_PARTIAL: break; /* H_NOT_AVAILABLE indicates reading from an offset outside the range, * i.e. past end of file.
*/ case H_NOT_AVAILABLE: return 0; case H_BUSY: case H_LONG_BUSY_ORDER_1_MSEC: case H_LONG_BUSY_ORDER_10_MSEC: case H_LONG_BUSY_ORDER_100_MSEC: case H_LONG_BUSY_ORDER_1_SEC: case H_LONG_BUSY_ORDER_10_SEC: case H_LONG_BUSY_ORDER_100_SEC: return -EBUSY; case H_PARAMETER: case H_P2: case H_P3: case H_P4: case H_P5: case H_P6: return -EINVAL; case H_STATE: return -EIO; case H_AUTHORITY: return -EPERM;
}
/* * Return 1 for H_SUCCESS/H_PARTIAL
*/ return 1;
}
/* * value as 1 : configure HTM. * value as 0 : deconfigure HTM. Return -EINVAL for * other values.
*/ if (val == HTM_ENABLE) { /* * Invoke H_HTM call with: * - operation as htm configure (H_HTM_OP_CONFIGURE) * - If htmflags is set, param1 and param2 will be -1 * which is an indicator to use default htm mode reg mask * and htm mode reg value. * - last three values are unused, hence set to zero
*/ if (!htmflags) {
param1 = 0;
param2 = 0;
}
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_CONFIGURE, param1, param2, 0);
} elseif (val == HTM_DISABLE) { /* * Invoke H_HTM call with: * - operation as htm deconfigure (H_HTM_OP_DECONFIGURE) * - last three values are unused, hence set to zero
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_DECONFIGURE, 0, 0, 0);
} else return -EINVAL;
ret = htm_return_check(rc); if (ret <= 0) {
pr_debug("H_HTM hcall failed, returning %ld\n", ret); return ret;
}
/* Set htmconfigure if operation succeeds */
htmconfigure = val;
staticint htmstart_set(void *data, u64 val)
{ long rc, ret;
/* * value as 1: start HTM * value as 0: stop HTM * Return -EINVAL for other values.
*/ if (val == HTM_ENABLE) { /* * Invoke H_HTM call with: * - operation as htm start (H_HTM_OP_START) * - last three values are unused, hence set to zero
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_START, 0, 0, 0);
} elseif (val == HTM_DISABLE) { /* * Invoke H_HTM call with: * - operation as htm stop (H_HTM_OP_STOP) * - last three values are unused, hence set to zero
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_STOP, 0, 0, 0);
} else return -EINVAL;
ret = htm_return_check(rc); if (ret <= 0) {
pr_debug("H_HTM hcall failed, returning %ld\n", ret); return ret;
}
/* Set htmstart if H_HTM_OP_START/H_HTM_OP_STOP operation succeeds */
htmstart = val;
/* * Invoke H_HTM call with: * - operation as htm status (H_HTM_OP_STATUS) * - last three values as addr, size and offset
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_buf),
PAGE_SIZE, 0);
ret = htm_return_check(rc); if (ret <= 0) {
pr_debug("H_HTM hcall failed for op: H_HTM_OP_STATUS, returning %ld\n", ret); return ret;
}
/* * HTM status buffer, start of buffer + 0x10 gives the * number of HTM entries in the buffer. Each nest htm status * entry is 0x6 bytes where each core htm status entry is * 0x8 bytes. * So total count to copy is: * 32 bytes (for first 7 fields) + (number of HTM entries * entry size)
*/
num_entries = htm_status_buf + 0x10; if (htmtype == 0x2)
htmstatus_flag = 0x8; else
htmstatus_flag = 0x6;
to_copy = 32 + (be64_to_cpu(*num_entries) * htmstatus_flag); return simple_read_from_buffer(ubuf, count, ppos, htm_status_buf, to_copy);
}
/* * Invoke H_HTM call with: * - operation as htm status (H_HTM_OP_STATUS) * - last three values as addr, size and offset
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_DUMP_SYSPROC_CONF, virt_to_phys(htm_info_buf),
PAGE_SIZE, 0);
ret = htm_return_check(rc); if (ret <= 0) {
pr_debug("H_HTM hcall failed for op: H_HTM_OP_DUMP_SYSPROC_CONF, returning %ld\n", ret); return ret;
}
/* * HTM status buffer, start of buffer + 0x10 gives the * number of HTM entries in the buffer. Each entry of processor * is 16 bytes. * * So total count to copy is: * 32 bytes (for first 5 fields) + (number of HTM entries * entry size)
*/
num_entries = htm_info_buf + 0x10;
to_copy = 32 + (be64_to_cpu(*num_entries) * 16); return simple_read_from_buffer(ubuf, count, ppos, htm_info_buf, to_copy);
}
staticint htmsetup_set(void *data, u64 val)
{ long rc, ret;
/* * Input value: HTM buffer size in the power of 2 * example: hex value 0x21 ( decimal: 33 ) is for * 8GB * Invoke H_HTM call with: * - operation as htm start (H_HTM_OP_SETUP) * - parameter 1 set to input value. * - last two values are unused, hence set to zero
*/
rc = htm_hcall_wrapper(htmflags, nodeindex, nodalchipindex, coreindexonchip,
htmtype, H_HTM_OP_SETUP, val, 0, 0);
ret = htm_return_check(rc); if (ret <= 0) {
pr_debug("H_HTM hcall failed for op: H_HTM_OP_SETUP, returning %ld\n", ret); return ret;
}
/* Set htmsetup if H_HTM_OP_SETUP operation succeeds */
htmsetup = val;
staticint htmflags_set(void *data, u64 val)
{ /* * Input value: * Currently supported flag value is to enable/disable * HTM buffer wrap. wrap is used along with "configure" * to prevent HTM buffer from wrapping. * Writing 1 will set noWrap while configuring HTM
*/ if (val == HTM_NOWRAP)
htmflags = H_HTM_FLAGS_NOWRAP; elseif (val == HTM_WRAP)
htmflags = 0; else return -EINVAL;
/* Debugfs interface file to present status of HTM */
htm_status_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!htm_status_buf) {
pr_err("Failed to allocate htmstatus buf\n"); return -ENOMEM;
}
/* Debugfs interface file to present System Processor Configuration */
htm_info_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!htm_info_buf) {
pr_err("Failed to allocate htm info buf\n"); return -ENOMEM;
}
/* Debugfs interface file to present HTM capabilities */
htm_caps_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!htm_caps_buf) {
pr_err("Failed to allocate htm caps buf\n"); return -ENOMEM;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.