cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dot_command.c (3385B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * IBM ASM Service Processor Device Driver
      4 *
      5 * Copyright (C) IBM Corporation, 2004
      6 *
      7 * Author: Max Asböck <amax@us.ibm.com>
      8 */
      9
     10#include "ibmasm.h"
     11#include "dot_command.h"
     12
     13/*
     14 * Dispatch an incoming message to the specific handler for the message.
     15 * Called from interrupt context.
     16 */
     17void ibmasm_receive_message(struct service_processor *sp, void *message, int message_size)
     18{
     19	u32 size;
     20	struct dot_command_header *header = (struct dot_command_header *)message;
     21
     22	if (message_size == 0)
     23		return;
     24
     25	size = get_dot_command_size(message);
     26	if (size == 0)
     27		return;
     28
     29	if (size > message_size)
     30		size = message_size;
     31
     32	switch (header->type) {
     33	case sp_event:
     34		ibmasm_receive_event(sp, message, size);
     35		break;
     36	case sp_command_response:
     37		ibmasm_receive_command_response(sp, message, size);
     38		break;
     39	case sp_heartbeat:
     40		ibmasm_receive_heartbeat(sp, message, size);
     41		break;
     42	default:
     43		dev_err(sp->dev, "Received unknown message from service processor\n");
     44	}
     45}
     46
     47
     48#define INIT_BUFFER_SIZE 32
     49
     50
     51/*
     52 * send the 4.3.5.10 dot command (driver VPD) to the service processor
     53 */
     54int ibmasm_send_driver_vpd(struct service_processor *sp)
     55{
     56	struct command *command;
     57	struct dot_command_header *header;
     58	u8 *vpd_command;
     59	u8 *vpd_data;
     60	int result = 0;
     61
     62	command = ibmasm_new_command(sp, INIT_BUFFER_SIZE);
     63	if (command == NULL)
     64		return -ENOMEM;
     65
     66	header = (struct dot_command_header *)command->buffer;
     67	header->type                = sp_write;
     68	header->command_size        = 4;
     69	header->data_size           = 16;
     70	header->status              = 0;
     71	header->reserved            = 0;
     72
     73	vpd_command = command->buffer + sizeof(struct dot_command_header);
     74	vpd_command[0] = 0x4;
     75	vpd_command[1] = 0x3;
     76	vpd_command[2] = 0x5;
     77	vpd_command[3] = 0xa;
     78
     79	vpd_data = vpd_command + header->command_size;
     80	vpd_data[0] = 0;
     81	strcat(vpd_data, IBMASM_DRIVER_VPD);
     82	vpd_data[10] = 0;
     83	vpd_data[15] = 0;
     84
     85	ibmasm_exec_command(sp, command);
     86	ibmasm_wait_for_response(command, IBMASM_CMD_TIMEOUT_NORMAL);
     87
     88	if (command->status != IBMASM_CMD_COMPLETE)
     89		result = -ENODEV;
     90
     91	command_put(command);
     92
     93	return result;
     94}
     95
     96struct os_state_command {
     97	struct dot_command_header	header;
     98	unsigned char			command[3];
     99	unsigned char			data;
    100};
    101
    102/*
    103 * send the 4.3.6 dot command (os state) to the service processor
    104 * During driver init this function is called with os state "up".
    105 * This causes the service processor to start sending heartbeats the
    106 * driver.
    107 * During driver exit the function is called with os state "down",
    108 * causing the service processor to stop the heartbeats.
    109 */
    110int ibmasm_send_os_state(struct service_processor *sp, int os_state)
    111{
    112	struct command *cmd;
    113	struct os_state_command *os_state_cmd;
    114	int result = 0;
    115
    116	cmd = ibmasm_new_command(sp, sizeof(struct os_state_command));
    117	if (cmd == NULL)
    118		return -ENOMEM;
    119
    120	os_state_cmd = (struct os_state_command *)cmd->buffer;
    121	os_state_cmd->header.type		= sp_write;
    122	os_state_cmd->header.command_size	= 3;
    123	os_state_cmd->header.data_size		= 1;
    124	os_state_cmd->header.status		= 0;
    125	os_state_cmd->command[0]		= 4;
    126	os_state_cmd->command[1]		= 3;
    127	os_state_cmd->command[2]		= 6;
    128	os_state_cmd->data			= os_state;
    129
    130	ibmasm_exec_command(sp, cmd);
    131	ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
    132
    133	if (cmd->status != IBMASM_CMD_COMPLETE)
    134		result = -ENODEV;
    135
    136	command_put(cmd);
    137	return result;
    138}