Commit 12e364b9 authored by Ken Cox's avatar Ken Cox Committed by Greg Kroah-Hartman

staging: visorchipset driver to provide registration and other services

The visorchipset module receives device creation and destruction
events from the Command service partition of s-Par, as well as
controlling registration of shared device drivers with the s-Par
driver core. The events received are used to populate other s-Par
modules with their assigned shared devices. Visorchipset is required
for shared device drivers to function properly. Visorchipset also
stores information for handling dump disk device creation during
kdump.

In operation, the visorchipset module processes device creation and
destruction messages sent by s-Par's Command service partition through
a channel. These messages result in creation (or destruction) of each
virtual bus and virtual device. Each bus and device is also associated
with a communication channel, which is used to communicate with one or
more IO service partitions to perform device IO on behalf of the
guest.
Signed-off-by: default avatarKen Cox <jkc@redhat.com>
Cc: Ben Romer <sparmaintainer@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e423812a
......@@ -11,5 +11,6 @@ if UNISYSSPAR
source "drivers/staging/unisys/visorutil/Kconfig"
source "drivers/staging/unisys/visorchannel/Kconfig"
source "drivers/staging/unisys/visorchipset/Kconfig"
endif # UNISYSSPAR
......@@ -3,4 +3,5 @@
#
obj-$(CONFIG_UNISYS_VISORUTIL) += visorutil/
obj-$(CONFIG_UNISYS_VISORCHANNEL) += visorchannel/
obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset/
/* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/*
* CHANNEL Guids
*/
/* Used in IOChannel
* {414815ed-c58c-11da-95a9-00e08161165f}
*/
#define ULTRA_VHBA_CHANNEL_PROTOCOL_GUID \
{ 0x414815ed, 0xc58c, 0x11da, \
{ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f } }
static const GUID UltraVhbaChannelProtocolGuid =
ULTRA_VHBA_CHANNEL_PROTOCOL_GUID;
/* Used in IOChannel
* {8cd5994d-c58e-11da-95a9-00e08161165f}
*/
#define ULTRA_VNIC_CHANNEL_PROTOCOL_GUID \
{ 0x8cd5994d, 0xc58e, 0x11da, \
{ 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f } }
static const GUID UltraVnicChannelProtocolGuid =
ULTRA_VNIC_CHANNEL_PROTOCOL_GUID;
/* Used in IOChannel
* {72120008-4AAB-11DC-8530-444553544200}
*/
#define ULTRA_SIOVM_GUID \
{ 0x72120008, 0x4AAB, 0x11DC, \
{ 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00 } }
static const GUID UltraSIOVMGuid = ULTRA_SIOVM_GUID;
/* Used in visornoop/visornoop_main.c
* {5b52c5ac-e5f5-4d42-8dff-429eaecd221f}
*/
#define ULTRA_CONTROLDIRECTOR_CHANNEL_PROTOCOL_GUID \
{ 0x5b52c5ac, 0xe5f5, 0x4d42, \
{ 0x8d, 0xff, 0x42, 0x9e, 0xae, 0xcd, 0x22, 0x1f } }
static const GUID UltraControlDirectorChannelProtocolGuid =
ULTRA_CONTROLDIRECTOR_CHANNEL_PROTOCOL_GUID;
/* Used in visorchipset/visorchipset_main.c
* {B4E79625-AEDE-4EAA-9E11-D3EDDCD4504C}
*/
#define ULTRA_DIAG_POOL_CHANNEL_PROTOCOL_GUID \
{0xb4e79625, 0xaede, 0x4eaa, \
{ 0x9e, 0x11, 0xd3, 0xed, 0xdc, 0xd4, 0x50, 0x4c } }
/* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/*
* Module Name:
* controlframework.h
*
* Abstract: This file defines common structures in the unmanaged
* Ultravisor (mostly EFI) space.
*
*/
#ifndef _CONTROL_FRAMEWORK_H_
#define _CONTROL_FRAMEWORK_H_
#include "commontypes.h"
#include "channel.h"
#define ULTRA_MEMORY_COUNT_Ki 1024
/* Scale order 0 is one 32-bit (4-byte) word (in 64 or 128-bit
* architecture potentially 64 or 128-bit word) */
#define ULTRA_MEMORY_PAGE_WORD 4
/* Define Ki scale page to be traditional 4KB page */
#define ULTRA_MEMORY_PAGE_Ki (ULTRA_MEMORY_PAGE_WORD * ULTRA_MEMORY_COUNT_Ki)
typedef struct _ULTRA_SEGMENT_STATE {
U16 Enabled:1; /* Bit 0: May enter other states */
U16 Active:1; /* Bit 1: Assigned to active partition */
U16 Alive:1; /* Bit 2: Configure message sent to
* service/server */
U16 Revoked:1; /* Bit 3: similar to partition state
* ShuttingDown */
U16 Allocated:1; /* Bit 4: memory (device/port number)
* has been selected by Command */
U16 Known:1; /* Bit 5: has been introduced to the
* service/guest partition */
U16 Ready:1; /* Bit 6: service/Guest partition has
* responded to introduction */
U16 Operating:1; /* Bit 7: resource is configured and
* operating */
/* Note: don't use high bit unless we need to switch to ushort
* which is non-compliant */
} ULTRA_SEGMENT_STATE;
static const ULTRA_SEGMENT_STATE SegmentStateRunning = {
1, 1, 1, 0, 1, 1, 1, 1
};
static const ULTRA_SEGMENT_STATE SegmentStatePaused = {
1, 1, 1, 0, 1, 1, 1, 0
};
static const ULTRA_SEGMENT_STATE SegmentStateStandby = {
1, 1, 0, 0, 1, 1, 1, 0
};
typedef union {
U64 Full;
struct {
U8 Major; /* will be 1 for the first release and
* increment thereafter */
U8 Minor;
U16 Maintenance;
U32 Revision; /* Subversion revision */
} Part;
} ULTRA_COMPONENT_VERSION;
#endif /* _CONTROL_FRAMEWORK_H_ not defined */
/* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __VBUSCHANNEL_H__
#define __VBUSCHANNEL_H__
/* The vbus channel is the channel area provided via the BUS_CREATE controlvm
* message for each virtual bus. This channel area is provided to both server
* and client ends of the bus. The channel header area is initialized by
* the server, and the remaining information is filled in by the client.
* We currently use this for the client to provide various information about
* the client devices and client drivers for the server end to see.
*/
#include "commontypes.h"
#include "vbusdeviceinfo.h"
#include "channel.h"
/* {193b331b-c58f-11da-95a9-00e08161165f} */
#define ULTRA_VBUS_CHANNEL_PROTOCOL_GUID \
{0x193b331b, 0xc58f, 0x11da, \
{0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f} }
static const GUID UltraVbusChannelProtocolGuid =
ULTRA_VBUS_CHANNEL_PROTOCOL_GUID;
#define ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE ULTRA_CHANNEL_PROTOCOL_SIGNATURE
/* Must increment this whenever you insert or delete fields within this channel
* struct. Also increment whenever you change the meaning of fields within this
* channel struct so as to break pre-existing software. Note that you can
* usually add fields to the END of the channel struct withOUT needing to
* increment this. */
#define ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID 1
#define ULTRA_VBUS_CHANNEL_OK_CLIENT(pChannel, logCtx) \
(ULTRA_check_channel_client(pChannel, \
UltraVbusChannelProtocolGuid, \
"vbus", \
sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL), \
ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID, \
ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE, \
__FILE__, __LINE__, logCtx))
#define ULTRA_VBUS_CHANNEL_OK_SERVER(actualBytes, logCtx) \
(ULTRA_check_channel_server(UltraVbusChannelProtocolGuid, \
"vbus", \
sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL), \
actualBytes, \
__FILE__, __LINE__, logCtx))
#pragma pack(push, 1) /* both GCC and VC now allow this pragma */
typedef struct _ULTRA_VBUS_HEADERINFO {
U32 structBytes; /* size of this struct in bytes */
U32 deviceInfoStructBytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */
U32 devInfoCount; /* num of items in DevInfo member */
/* (this is the allocated size) */
U32 chpInfoByteOffset; /* byte offset from beginning of this struct */
/* to the the ChpInfo struct (below) */
U32 busInfoByteOffset; /* byte offset from beginning of this struct */
/* to the the BusInfo struct (below) */
U32 devInfoByteOffset; /* byte offset from beginning of this struct */
/* to the the DevInfo array (below) */
U8 reserved[104];
} ULTRA_VBUS_HEADERINFO;
typedef struct _ULTRA_VBUS_CHANNEL_PROTOCOL {
ULTRA_CHANNEL_PROTOCOL ChannelHeader; /* initialized by server */
ULTRA_VBUS_HEADERINFO HdrInfo; /* initialized by server */
/* the remainder of this channel is filled in by the client */
ULTRA_VBUS_DEVICEINFO ChpInfo; /* describes client chipset device and
* driver */
ULTRA_VBUS_DEVICEINFO BusInfo; /* describes client bus device and
* driver */
ULTRA_VBUS_DEVICEINFO DevInfo[0]; /* describes client device and
* driver for */
/* each device on the bus */
} ULTRA_VBUS_CHANNEL_PROTOCOL;
#define VBUS_CH_SIZE_EXACT(MAXDEVICES) \
(sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL) + ((MAXDEVICES) * \
sizeof(ULTRA_VBUS_DEVICEINFO)))
#define VBUS_CH_SIZE(MAXDEVICES) COVER(VBUS_CH_SIZE_EXACT(MAXDEVICES), 4096)
static INLINE void
ULTRA_VBUS_init_channel(ULTRA_VBUS_CHANNEL_PROTOCOL *x, int bytesAllocated)
{
/* Please note that the memory at <x> does NOT necessarily have space
* for DevInfo structs allocated at the end, which is why we do NOT use
* <bytesAllocated> to clear. */
MEMSET(x, 0, sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL));
if (bytesAllocated < (int) sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL))
return;
x->ChannelHeader.VersionId = ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID;
x->ChannelHeader.Signature = ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE;
x->ChannelHeader.SrvState = CHANNELSRV_READY;
x->ChannelHeader.HeaderSize = sizeof(x->ChannelHeader);
x->ChannelHeader.Size = bytesAllocated;
x->ChannelHeader.Type = UltraVbusChannelProtocolGuid;
x->ChannelHeader.ZoneGuid = Guid0;
x->HdrInfo.structBytes = sizeof(ULTRA_VBUS_HEADERINFO);
x->HdrInfo.chpInfoByteOffset = sizeof(ULTRA_VBUS_HEADERINFO);
x->HdrInfo.busInfoByteOffset = x->HdrInfo.chpInfoByteOffset
+ sizeof(ULTRA_VBUS_DEVICEINFO);
x->HdrInfo.devInfoByteOffset = x->HdrInfo.busInfoByteOffset
+ sizeof(ULTRA_VBUS_DEVICEINFO);
x->HdrInfo.deviceInfoStructBytes = sizeof(ULTRA_VBUS_DEVICEINFO);
bytesAllocated -= (sizeof(ULTRA_CHANNEL_PROTOCOL)
+ x->HdrInfo.devInfoByteOffset);
x->HdrInfo.devInfoCount =
bytesAllocated / x->HdrInfo.deviceInfoStructBytes;
}
#pragma pack(pop)
#endif
/* controlvmcompletionstatus.c
*
* Copyright 2010 - 2013 UNISYS CORPORATION
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/* Defines for all valid values returned in the response message header
* completionStatus field. See controlvmchannel.h for description of
* the header: _CONTROLVM_MESSAGE_HEADER.
*/
#ifndef __CONTROLVMCOMPLETIONSTATUS_H__
#define __CONTROLVMCOMPLETIONSTATUS_H__
/* General Errors------------------------------------------------------[0-99] */
#define CONTROLVM_RESP_SUCCESS 0
#define CONTROLVM_RESP_ERROR_ALREADY_DONE 1
#define CONTROLVM_RESP_ERROR_IOREMAP_FAILED 2
#define CONTROLVM_RESP_ERROR_KMALLOC_FAILED 3
#define CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN 4
#define CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT 5
/* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */
#define CONTROLVM_RESP_ERROR_CLIENT_SWITCHCOUNT_NONZERO 100
#define CONTROLVM_RESP_ERROR_EXPECTED_CHIPSET_INIT 101
/* Maximum Limit----------------------------------------------------[200-299] */
#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */
#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */
/* Payload and Parameter Related------------------------------------[400-499] */
#define CONTROLVM_RESP_ERROR_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT,
* DEVICE_CONFIGURE */
#define CONTROLVM_RESP_ERROR_INITIATOR_PARAMETER_INVALID 401 /* Multiple */
#define CONTROLVM_RESP_ERROR_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */
#define CONTROLVM_RESP_ERROR_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */
/* Specified[Packet Structure] Value-------------------------------[500-599] */
#define CONTROLVM_RESP_ERROR_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT,
* BUS_CONFIGURE,
* DEVICE_CREATE,
* DEVICE_CONFIG
* DEVICE_DESTROY */
#define CONTROLVM_RESP_ERROR_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */
/* DEVICE_CREATE,
* DEVICE_CONFIGURE,
* DEVICE_DESTROY */
#define CONTROLVM_RESP_ERROR_CHANNEL_INVALID 502 /* DEVICE_CREATE,
* DEVICE_CONFIGURE */
/* Partition Driver Callback Interface----------------------[600-699] */
#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE,
* BUS_DESTROY,
* DEVICE_CREATE,
* DEVICE_DESTROY */
/* Unable to invoke VIRTPCI callback */
#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE,
* BUS_DESTROY,
* DEVICE_CREATE,
* DEVICE_DESTROY */
/* VIRTPCI Callback returned error */
#define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606 /* SWITCH_ATTACHEXTPORT,
* SWITCH_DETACHEXTPORT
* DEVICE_CONFIGURE */
/* generic device callback returned error */
/* Bus Related------------------------------------------------------[700-799] */
#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */
/* Channel Related--------------------------------------------------[800-899] */
#define CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO,
* DEVICE_DESTROY */
#define CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */
/* Chipset Shutdown Related---------------------------------------[1000-1099] */
#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_FAILED 1000
#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001
/* Chipset Stop Related-------------------------------------------[1100-1199] */
#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS 1100
#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_SWITCH 1101
/* Device Related-------------------------------------------------[1400-1499] */
#define CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT 1400
#endif /* __CONTROLVMCOMPLETIONSTATUS_H__ not defined */
/* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/* Please note that this file is to be used ONLY for defining diagnostic
* subsystem values for the appos (sPAR Linux service partitions) component.
*/
#ifndef __APPOS_SUBSYSTEMS_H__
#define __APPOS_SUBSYSTEMS_H__
#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/string.h>
#else
#include <stdio.h>
#include <string.h>
#endif
static inline char *
subsys_unknown_to_s(int subsys, char *s, int n)
{
snprintf(s, n, "SUBSYS-%-2.2d", subsys);
s[n - 1] = '\0';
return s;
}
#define SUBSYS_TO_MASK(subsys) (1ULL << (subsys))
/* The first SUBSYS_APPOS_MAX subsystems are the same for each AppOS type
* (IOVM, SMS, etc.) The rest have unique values for each AppOS type.
*/
#define SUBSYS_APPOS_MAX 16
#define SUBSYS_APPOS_DEFAULT 1 /* or "other" */
#define SUBSYS_APPOS_CHIPSET 2 /* controlvm and other */
/* low-level sPAR activity */
#define SUBSYS_APPOS_BUS 3 /* sPAR bus */
/* DAK #define SUBSYS_APPOS_DIAG 4 // diagnostics and dump */
#define SUBSYS_APPOS_CHANNELACCESS 5 /* generic channel access */
#define SUBSYS_APPOS_NICCLIENT 6 /* virtual NIC client */
#define SUBSYS_APPOS_HBACLIENT 7 /* virtual HBA client */
#define SUBSYS_APPOS_CONSOLESERIAL 8 /* sPAR virtual serial console */
#define SUBSYS_APPOS_UISLIB 9 /* */
#define SUBSYS_APPOS_VRTCUPDD 10 /* */
#define SUBSYS_APPOS_WATCHDOG 11 /* watchdog timer and healthcheck */
#define SUBSYS_APPOS_13 13 /* available */
#define SUBSYS_APPOS_14 14 /* available */
#define SUBSYS_APPOS_15 15 /* available */
#define SUBSYS_APPOS_16 16 /* available */
static inline char *
subsys_generic_to_s(int subsys, char *s, int n)
{
switch (subsys) {
case SUBSYS_APPOS_DEFAULT:
strncpy(s, "APPOS_DEFAULT", n);
break;
case SUBSYS_APPOS_CHIPSET:
strncpy(s, "APPOS_CHIPSET", n);
break;
case SUBSYS_APPOS_BUS:
strncpy(s, "APPOS_BUS", n);
break;
case SUBSYS_APPOS_CHANNELACCESS:
strncpy(s, "APPOS_CHANNELACCESS", n);
break;
case SUBSYS_APPOS_NICCLIENT:
strncpy(s, "APPOS_NICCLIENT", n);
break;
case SUBSYS_APPOS_HBACLIENT:
strncpy(s, "APPOS_HBACLIENT", n);
break;
case SUBSYS_APPOS_CONSOLESERIAL:
strncpy(s, "APPOS_CONSOLESERIAL", n);
break;
case SUBSYS_APPOS_UISLIB:
strncpy(s, "APPOS_UISLIB", n);
break;
case SUBSYS_APPOS_VRTCUPDD:
strncpy(s, "APPOS_VRTCUPDD", n);
break;
case SUBSYS_APPOS_WATCHDOG:
strncpy(s, "APPOS_WATCHDOG", n);
break;
case SUBSYS_APPOS_13:
strncpy(s, "APPOS_13", n);
break;
case SUBSYS_APPOS_14:
strncpy(s, "APPOS_14", n);
break;
case SUBSYS_APPOS_15:
strncpy(s, "APPOS_15", n);
break;
case SUBSYS_APPOS_16:
strncpy(s, "APPOS_16", n);
break;
default:
subsys_unknown_to_s(subsys, s, n);
break;
}
s[n - 1] = '\0';
return s;
}
/* CONSOLE */
#define SUBSYS_CONSOLE_VIDEO (SUBSYS_APPOS_MAX + 1) /* 17 */
#define SUBSYS_CONSOLE_KBDMOU (SUBSYS_APPOS_MAX + 2) /* 18 */
#define SUBSYS_CONSOLE_04 (SUBSYS_APPOS_MAX + 4)
#define SUBSYS_CONSOLE_05 (SUBSYS_APPOS_MAX + 5)
#define SUBSYS_CONSOLE_06 (SUBSYS_APPOS_MAX + 6)
#define SUBSYS_CONSOLE_07 (SUBSYS_APPOS_MAX + 7)
#define SUBSYS_CONSOLE_08 (SUBSYS_APPOS_MAX + 8)
#define SUBSYS_CONSOLE_09 (SUBSYS_APPOS_MAX + 9)
#define SUBSYS_CONSOLE_10 (SUBSYS_APPOS_MAX + 10)
#define SUBSYS_CONSOLE_11 (SUBSYS_APPOS_MAX + 11)
#define SUBSYS_CONSOLE_12 (SUBSYS_APPOS_MAX + 12)
#define SUBSYS_CONSOLE_13 (SUBSYS_APPOS_MAX + 13)
#define SUBSYS_CONSOLE_14 (SUBSYS_APPOS_MAX + 14)
#define SUBSYS_CONSOLE_15 (SUBSYS_APPOS_MAX + 15)
#define SUBSYS_CONSOLE_16 (SUBSYS_APPOS_MAX + 16)
#define SUBSYS_CONSOLE_17 (SUBSYS_APPOS_MAX + 17)
#define SUBSYS_CONSOLE_18 (SUBSYS_APPOS_MAX + 18)
#define SUBSYS_CONSOLE_19 (SUBSYS_APPOS_MAX + 19)
#define SUBSYS_CONSOLE_20 (SUBSYS_APPOS_MAX + 20)
#define SUBSYS_CONSOLE_21 (SUBSYS_APPOS_MAX + 21)
#define SUBSYS_CONSOLE_22 (SUBSYS_APPOS_MAX + 22)
#define SUBSYS_CONSOLE_23 (SUBSYS_APPOS_MAX + 23)
#define SUBSYS_CONSOLE_24 (SUBSYS_APPOS_MAX + 24)
#define SUBSYS_CONSOLE_25 (SUBSYS_APPOS_MAX + 25)
#define SUBSYS_CONSOLE_26 (SUBSYS_APPOS_MAX + 26)
#define SUBSYS_CONSOLE_27 (SUBSYS_APPOS_MAX + 27)
#define SUBSYS_CONSOLE_28 (SUBSYS_APPOS_MAX + 28)
#define SUBSYS_CONSOLE_29 (SUBSYS_APPOS_MAX + 29)
#define SUBSYS_CONSOLE_30 (SUBSYS_APPOS_MAX + 30)
#define SUBSYS_CONSOLE_31 (SUBSYS_APPOS_MAX + 31)
#define SUBSYS_CONSOLE_32 (SUBSYS_APPOS_MAX + 32)
#define SUBSYS_CONSOLE_33 (SUBSYS_APPOS_MAX + 33)
#define SUBSYS_CONSOLE_34 (SUBSYS_APPOS_MAX + 34)
#define SUBSYS_CONSOLE_35 (SUBSYS_APPOS_MAX + 35)
#define SUBSYS_CONSOLE_36 (SUBSYS_APPOS_MAX + 36)
#define SUBSYS_CONSOLE_37 (SUBSYS_APPOS_MAX + 37)
#define SUBSYS_CONSOLE_38 (SUBSYS_APPOS_MAX + 38)
#define SUBSYS_CONSOLE_39 (SUBSYS_APPOS_MAX + 39)
#define SUBSYS_CONSOLE_40 (SUBSYS_APPOS_MAX + 40)
#define SUBSYS_CONSOLE_41 (SUBSYS_APPOS_MAX + 41)
#define SUBSYS_CONSOLE_42 (SUBSYS_APPOS_MAX + 42)
#define SUBSYS_CONSOLE_43 (SUBSYS_APPOS_MAX + 43)
#define SUBSYS_CONSOLE_44 (SUBSYS_APPOS_MAX + 44)
#define SUBSYS_CONSOLE_45 (SUBSYS_APPOS_MAX + 45)
#define SUBSYS_CONSOLE_46 (SUBSYS_APPOS_MAX + 46)
static inline char *
subsys_console_to_s(int subsys, char *s, int n)
{
switch (subsys) {
case SUBSYS_CONSOLE_VIDEO:
strncpy(s, "CONSOLE_VIDEO", n);
break;
case SUBSYS_CONSOLE_KBDMOU:
strncpy(s, "CONSOLE_KBDMOU", n);
break;
case SUBSYS_CONSOLE_04:
strncpy(s, "CONSOLE_04", n);
break;
case SUBSYS_CONSOLE_05:
strncpy(s, "CONSOLE_05", n);
break;
case SUBSYS_CONSOLE_06:
strncpy(s, "CONSOLE_06", n);
break;
case SUBSYS_CONSOLE_07:
strncpy(s, "CONSOLE_07", n);
break;
case SUBSYS_CONSOLE_08:
strncpy(s, "CONSOLE_08", n);
break;
case SUBSYS_CONSOLE_09:
strncpy(s, "CONSOLE_09", n);
break;
case SUBSYS_CONSOLE_10:
strncpy(s, "CONSOLE_10", n);
break;
case SUBSYS_CONSOLE_11:
strncpy(s, "CONSOLE_11", n);
break;
case SUBSYS_CONSOLE_12:
strncpy(s, "CONSOLE_12", n);
break;
case SUBSYS_CONSOLE_13:
strncpy(s, "CONSOLE_13", n);
break;
case SUBSYS_CONSOLE_14:
strncpy(s, "CONSOLE_14", n);
break;
case SUBSYS_CONSOLE_15:
strncpy(s, "CONSOLE_15", n);
break;
case SUBSYS_CONSOLE_16:
strncpy(s, "CONSOLE_16", n);
break;
case SUBSYS_CONSOLE_17:
strncpy(s, "CONSOLE_17", n);
break;
case SUBSYS_CONSOLE_18:
strncpy(s, "CONSOLE_18", n);
break;
case SUBSYS_CONSOLE_19:
strncpy(s, "CONSOLE_19", n);
break;
case SUBSYS_CONSOLE_20:
strncpy(s, "CONSOLE_20", n);
break;
case SUBSYS_CONSOLE_21:
strncpy(s, "CONSOLE_21", n);
break;
case SUBSYS_CONSOLE_22:
strncpy(s, "CONSOLE_22", n);
break;
case SUBSYS_CONSOLE_23:
strncpy(s, "CONSOLE_23", n);
break;
case SUBSYS_CONSOLE_24:
strncpy(s, "CONSOLE_24", n);
break;
case SUBSYS_CONSOLE_25:
strncpy(s, "CONSOLE_25", n);
break;
case SUBSYS_CONSOLE_26:
strncpy(s, "CONSOLE_26", n);
break;
case SUBSYS_CONSOLE_27:
strncpy(s, "CONSOLE_27", n);
break;
case SUBSYS_CONSOLE_28:
strncpy(s, "CONSOLE_28", n);
break;
case SUBSYS_CONSOLE_29:
strncpy(s, "CONSOLE_29", n);
break;
case SUBSYS_CONSOLE_30:
strncpy(s, "CONSOLE_30", n);
break;
case SUBSYS_CONSOLE_31:
strncpy(s, "CONSOLE_31", n);
break;
case SUBSYS_CONSOLE_32:
strncpy(s, "CONSOLE_32", n);
break;
case SUBSYS_CONSOLE_33:
strncpy(s, "CONSOLE_33", n);
break;
case SUBSYS_CONSOLE_34:
strncpy(s, "CONSOLE_34", n);
break;
case SUBSYS_CONSOLE_35:
strncpy(s, "CONSOLE_35", n);
break;
case SUBSYS_CONSOLE_36:
strncpy(s, "CONSOLE_36", n);
break;
case SUBSYS_CONSOLE_37:
strncpy(s, "CONSOLE_37", n);
break;
case SUBSYS_CONSOLE_38:
strncpy(s, "CONSOLE_38", n);
break;
case SUBSYS_CONSOLE_39:
strncpy(s, "CONSOLE_39", n);
break;
case SUBSYS_CONSOLE_40:
strncpy(s, "CONSOLE_40", n);
break;
case SUBSYS_CONSOLE_41:
strncpy(s, "CONSOLE_41", n);
break;
case SUBSYS_CONSOLE_42:
strncpy(s, "CONSOLE_42", n);
break;
case SUBSYS_CONSOLE_43:
strncpy(s, "CONSOLE_43", n);
break;
case SUBSYS_CONSOLE_44:
strncpy(s, "CONSOLE_44", n);
break;
case SUBSYS_CONSOLE_45:
strncpy(s, "CONSOLE_45", n);
break;
case SUBSYS_CONSOLE_46:
strncpy(s, "CONSOLE_46", n);
break;
default:
subsys_unknown_to_s(subsys, s, n);
break;
}
s[n - 1] = '\0';
return s;
}
#endif
/* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/* Linux GCC Version (32-bit and 64-bit) */
static inline unsigned long
__unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx,
unsigned long reg_ecx)
{
unsigned long result = 0;
unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
if (cpuid_ecx & 0x80000000) {
__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
"a"(tuple), "b"(reg_ebx), "c"(reg_ecx)
);
} else {
result = -1;
}
return result;
}
static inline unsigned long
__unisys_extended_vmcall_gnuc(unsigned long long tuple,
unsigned long long reg_ebx,
unsigned long long reg_ecx,
unsigned long long reg_edx)
{
unsigned long result = 0;
unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
if (cpuid_ecx & 0x80000000) {
__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
"a"(tuple), "b"(reg_ebx), "c"(reg_ecx),
"d"(reg_edx));
} else {
result = -1;
}
return result;
}
/* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __VBUSDEVICEINFO_H__
#define __VBUSDEVICEINFO_H__
#include "commontypes.h"
#pragma pack(push, 1) /* both GCC and VC now allow this pragma */
/* An array of this struct is present in the channel area for each vbus.
* (See vbuschannel.h.)
* It is filled in by the client side to provide info about the device
* and driver from the client's perspective.
*/
typedef struct _ULTRA_VBUS_DEVICEINFO {
U8 devType[16]; /* short string identifying the device type */
U8 drvName[16]; /* driver .sys file name */
U8 infoStrings[96]; /* sequence of tab-delimited id strings: */
/* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */
U8 reserved[128]; /* pad size to 256 bytes */
} ULTRA_VBUS_DEVICEINFO;
#pragma pack(pop)
/* Reads chars from the buffer at <src> for <srcmax> bytes, and writes to
* the buffer at <p>, which is <remain> bytes long, ensuring never to
* overflow the buffer at <p>, using the following rules:
* - printable characters are simply copied from the buffer at <src> to the
* buffer at <p>
* - intervening streaks of non-printable characters in the buffer at <src>
* are replaced with a single space in the buffer at <p>
* Note that we pay no attention to '\0'-termination.
* Returns the number of bytes written to <p>.
*
* Pass <p> == NULL and <remain> == 0 for this special behavior. In this
* case, we simply return the number of bytes that WOULD HAVE been written
* to a buffer at <p>, had it been infinitely big.
*/
static inline int
VBUSCHANNEL_sanitize_buffer(char *p, int remain, char *src, int srcmax)
{
int chars = 0;
int nonprintable_streak = 0;
while (srcmax > 0) {
if ((*src >= ' ') && (*src < 0x7f)) {
if (nonprintable_streak) {
if (remain > 0) {
*p = ' ';
p++;
remain--;
chars++;
} else if (p == NULL)
chars++;
nonprintable_streak = 0;
}
if (remain > 0) {
*p = *src;
p++;
remain--;
chars++;
} else if (p == NULL)
chars++;
} else
nonprintable_streak = 1;
src++;
srcmax--;
}
return chars;
}
#define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \
do { \
if (remain <= 0) \
break; \
*p = ch; \
p++; chars++; remain--; \
} while (0)
/* Converts the non-negative value at <num> to an ascii decimal string
* at <p>, writing at most <remain> bytes. Note there is NO '\0' termination
* written to <p>.
*
* Returns the number of bytes written to <p>.
*
* Note that we create this function because we need to do this operation in
* an environment-independent way (since we are in a common header file).
*/
static inline int
VBUSCHANNEL_itoa(char *p, int remain, int num)
{
int digits = 0;
char s[32];
int i;
if (num == 0) {
/* '0' is a special case */
if (remain <= 0)
return 0;
*p = '0';
return 1;
}
/* form a backwards decimal ascii string in <s> */
while (num > 0) {
if (digits >= (int) sizeof(s))
return 0;
s[digits++] = (num % 10) + '0';
num = num / 10;
}
if (remain < digits) {
/* not enough room left at <p> to hold number, so fill with
* '?' */
for (i = 0; i < remain; i++, p++)
*p = '?';
return remain;
}
/* plug in the decimal ascii string representing the number, by */
/* reversing the string we just built in <s> */
i = digits;
while (i > 0) {
i--;
*p = s[i];
p++;
}
return digits;
}
/* Reads <devInfo>, and converts its contents to a printable string at <p>,
* writing at most <remain> bytes. Note there is NO '\0' termination
* written to <p>.
*
* Pass <devix> >= 0 if you want a device index presented.
*
* Returns the number of bytes written to <p>.
*/
static inline int
VBUSCHANNEL_devInfoToStringBuffer(ULTRA_VBUS_DEVICEINFO devInfo,
char *p, int remain, int devix)
{
char *psrc;
int nsrc, x, i, pad;
int chars = 0;
psrc = &(devInfo.devType[0]);
nsrc = sizeof(devInfo.devType);
if (VBUSCHANNEL_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
return 0;
/* emit device index */
if (devix >= 0) {
VBUSCHANNEL_ADDACHAR('[', p, remain, chars);
x = VBUSCHANNEL_itoa(p, remain, devix);
p += x;
remain -= x;
chars += x;
VBUSCHANNEL_ADDACHAR(']', p, remain, chars);
} else {
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
}
/* emit device type */
x = VBUSCHANNEL_sanitize_buffer(p, remain, psrc, nsrc);
p += x;
remain -= x;
chars += x;
pad = 15 - x; /* pad device type to be exactly 15 chars */
for (i = 0; i < pad; i++)
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
/* emit driver name */
psrc = &(devInfo.drvName[0]);
nsrc = sizeof(devInfo.drvName);
x = VBUSCHANNEL_sanitize_buffer(p, remain, psrc, nsrc);
p += x;
remain -= x;
chars += x;
pad = 15 - x; /* pad driver name to be exactly 15 chars */
for (i = 0; i < pad; i++)
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
/* emit strings */
psrc = &(devInfo.infoStrings[0]);
nsrc = sizeof(devInfo.infoStrings);
x = VBUSCHANNEL_sanitize_buffer(p, remain, psrc, nsrc);
p += x;
remain -= x;
chars += x;
VBUSCHANNEL_ADDACHAR('\n', p, remain, chars);
return chars;
}
#endif
/* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __IOMONINTF_H__
#define __IOMONINTF_H__
/*
* This file contains all structures needed to support the VMCALLs for IO
* Virtualization. The VMCALLs are provided by Monitor and used by IO code
* running on IO Partitions.
*/
#ifdef __GNUC__
#include "iovmcall_gnuc.h"
#endif /* */
#include "diagchannel.h"
#ifdef VMCALL_IO_CONTROLVM_ADDR
#undef VMCALL_IO_CONTROLVM_ADDR
#endif /* */
/* define subsystem number for AppOS, used in uislib driver */
#define MDS_APPOS 0x4000000000000000 /* subsystem = 62 - AppOS */
typedef enum { /* VMCALL identification tuples */
/* Note: when a new VMCALL is added:
* - the 1st 2 hex digits correspond to one of the
* VMCALL_MONITOR_INTERFACE types and
* - the next 2 hex digits are the nth relative instance of within a
* type
* E.G. for VMCALL_VIRTPART_RECYCLE_PART,
* - the 0x02 identifies it as a VMCALL_VIRTPART type and
* - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART
* type of VMCALL
*/
VMCALL_IO_CONTROLVM_ADDR = 0x0501, /* used by all Guests, not just
* IO */
VMCALL_IO_DIAG_ADDR = 0x0508,
VMCALL_IO_VISORSERIAL_ADDR = 0x0509,
VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET = 0x0708, /* Allow caller to
* query virtual time
* offset */
VMCALL_CHANNEL_VERSION_MISMATCH = 0x0709,
VMCALL_POST_CODE_LOGEVENT = 0x070B, /* LOGEVENT Post Code (RDX) with
* specified subsystem mask (RCX
* - monitor_subsystems.h) and
* severity (RDX) */
VMCALL_GENERIC_SURRENDER_QUANTUM_FOREVER = 0x0802, /* Yield the
* remainder & all
* future quantums of
* the caller */
VMCALL_MEASUREMENT_DO_NOTHING = 0x0901,
VMCALL_UPDATE_PHYSICAL_TIME = 0x0a02 /* Allow
* ULTRA_SERVICE_CAPABILITY_TIME
* capable guest to make
* VMCALL */
} VMCALL_MONITOR_INTERFACE_METHOD_TUPLE;
#define VMCALL_SUCCESS 0
#define VMCALL_SUCCESSFUL(result) (result == 0)
#ifdef __GNUC__
#define unisys_vmcall(tuple, reg_ebx, reg_ecx) \
__unisys_vmcall_gnuc(tuple, reg_ebx, reg_ecx)
#define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \
__unisys_extended_vmcall_gnuc(tuple, reg_ebx, reg_ecx, reg_edx)
#define ISSUE_IO_VMCALL(InterfaceMethod, param, result) \
(result = unisys_vmcall(InterfaceMethod, (param) & 0xFFFFFFFF, \
(param) >> 32))
#define ISSUE_IO_EXTENDED_VMCALL(InterfaceMethod, param1, param2, \
param3, result) \
(result = unisys_extended_vmcall(InterfaceMethod, param1, \
param2, param3))
/* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently
* not used much */
#define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \
do { \
U32 _tempresult = VMCALL_SUCCESS; \
ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \
MDS_APPOS, postcode, _tempresult); \
} while (0)
#endif
/* Structures for IO VMCALLs */
/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
#pragma pack(push, 1)
struct phys_info {
U64 pi_pfn;
U16 pi_off;
U16 pi_len;
};
#pragma pack(pop)
/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
typedef struct phys_info IO_DATA_STRUCTURE;
/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
#pragma pack(push, 1)
/* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */
typedef struct _VMCALL_IO_CONTROLVM_ADDR_PARAMS {
/* The Guest-relative physical address of the ControlVm channel.
* This VMCall fills this in with the appropriate address. */
U64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
/* the size of the ControlVm channel in bytes This VMCall fills this
* in with the appropriate address. */
U32 ChannelBytes; /* contents provided by this VMCALL (OUT) */
U8 Unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */
} VMCALL_IO_CONTROLVM_ADDR_PARAMS;
#pragma pack(pop)
/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
#pragma pack(push, 1)
/* Parameters to VMCALL_IO_DIAG_ADDR interface */
typedef struct _VMCALL_IO_DIAG_ADDR_PARAMS {
/* The Guest-relative physical address of the diagnostic channel.
* This VMCall fills this in with the appropriate address. */
U64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
} VMCALL_IO_DIAG_ADDR_PARAMS;
#pragma pack(pop)
/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
#pragma pack(push, 1)
/* Parameters to VMCALL_IO_VISORSERIAL_ADDR interface */
typedef struct _VMCALL_IO_VISORSERIAL_ADDR_PARAMS {
/* The Guest-relative physical address of the serial console
* channel. This VMCall fills this in with the appropriate
* address. */
U64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
} VMCALL_IO_VISORSERIAL_ADDR_PARAMS;
#pragma pack(pop)
/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
/* Parameters to VMCALL_CHANNEL_MISMATCH interface */
typedef struct _VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS {
U8 ChannelName[32]; /* Null terminated string giving name of channel
* (IN) */
U8 ItemName[32]; /* Null terminated string giving name of
* mismatched item (IN) */
U32 SourceLineNumber; /* line# where invoked. (IN) */
U8 SourceFileName[36]; /* source code where invoked - Null terminated
* string (IN) */
} VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS;
#endif /* __IOMONINTF_H__ */
/* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __GUESTLINUXDEBUG_H__
#define __GUESTLINUXDEBUG_H__
/*
* This file contains supporting interface for "vmcallinterface.h", particuarly
* regarding adding additional structure and functionality to linux
* ISSUE_IO_VMCALL_POSTCODE_SEVERITY */
/******* INFO ON ISSUE_POSTCODE_LINUX() BELOW *******/
#include "vmcallinterface.h"
typedef enum { /* POSTCODE driver identifier tuples */
/* visorchipset driver files */
VISOR_CHIPSET_PC = 0xA0,
VISOR_CHIPSET_PC_controlvm_c = 0xA1,
VISOR_CHIPSET_PC_controlvm_cm2 = 0xA2,
VISOR_CHIPSET_PC_controlvm_direct_c = 0xA3,
VISOR_CHIPSET_PC_file_c = 0xA4,
VISOR_CHIPSET_PC_parser_c = 0xA5,
VISOR_CHIPSET_PC_testing_c = 0xA6,
VISOR_CHIPSET_PC_visorchipset_main_c = 0xA7,
VISOR_CHIPSET_PC_visorswitchbus_c = 0xA8,
/* visorbus driver files */
VISOR_BUS_PC = 0xB0,
VISOR_BUS_PC_businst_attr_c = 0xB1,
VISOR_BUS_PC_channel_attr_c = 0xB2,
VISOR_BUS_PC_devmajorminor_attr_c = 0xB3,
VISOR_BUS_PC_visorbus_main_c = 0xB4,
/* visorclientbus driver files */
VISOR_CLIENT_BUS_PC = 0xC0,
VISOR_CLIENT_BUS_PC_visorclientbus_main_c = 0xC1,
/* virt hba driver files */
VIRT_HBA_PC = 0xC2,
VIRT_HBA_PC_virthba_c = 0xC3,
/* virtpci driver files */
VIRT_PCI_PC = 0xC4,
VIRT_PCI_PC_virtpci_c = 0xC5,
/* virtnic driver files */
VIRT_NIC_PC = 0xC6,
VIRT_NIC_P_virtnic_c = 0xC7,
/* uislib driver files */
UISLIB_PC = 0xD0,
UISLIB_PC_uislib_c = 0xD1,
UISLIB_PC_uisqueue_c = 0xD2,
UISLIB_PC_uisthread_c = 0xD3,
UISLIB_PC_uisutils_c = 0xD4,
} DRIVER_PC;
typedef enum { /* POSTCODE event identifier tuples */
ATTACH_PORT_ENTRY_PC = 0x001,
ATTACH_PORT_FAILURE_PC = 0x002,
ATTACH_PORT_SUCCESS_PC = 0x003,
BUS_FAILURE_PC = 0x004,
BUS_CREATE_ENTRY_PC = 0x005,
BUS_CREATE_FAILURE_PC = 0x006,
BUS_CREATE_EXIT_PC = 0x007,
BUS_CONFIGURE_ENTRY_PC = 0x008,
BUS_CONFIGURE_FAILURE_PC = 0x009,
BUS_CONFIGURE_EXIT_PC = 0x00A,
CHIPSET_INIT_ENTRY_PC = 0x00B,
CHIPSET_INIT_SUCCESS_PC = 0x00C,
CHIPSET_INIT_FAILURE_PC = 0x00D,
CHIPSET_INIT_EXIT_PC = 0x00E,
CREATE_WORKQUEUE_PC = 0x00F,
CREATE_WORKQUEUE_FAILED_PC = 0x0A0,
CONTROLVM_INIT_FAILURE_PC = 0x0A1,
DEVICE_CREATE_ENTRY_PC = 0x0A2,
DEVICE_CREATE_FAILURE_PC = 0x0A3,
DEVICE_CREATE_SUCCESS_PC = 0x0A4,
DEVICE_CREATE_EXIT_PC = 0x0A5,
DEVICE_ADD_PC = 0x0A6,
DEVICE_REGISTER_FAILURE_PC = 0x0A7,
DEVICE_CHANGESTATE_ENTRY_PC = 0x0A8,
DEVICE_CHANGESTATE_FAILURE_PC = 0x0A9,
DEVICE_CHANGESTATE_EXIT_PC = 0x0AA,
DRIVER_ENTRY_PC = 0x0AB,
DRIVER_EXIT_PC = 0x0AC,
MALLOC_FAILURE_PC = 0x0AD,
QUEUE_DELAYED_WORK_PC = 0x0AE,
UISLIB_THREAD_FAILURE_PC = 0x0B7,
VBUS_CHANNEL_ENTRY_PC = 0x0B8,
VBUS_CHANNEL_FAILURE_PC = 0x0B9,
VBUS_CHANNEL_EXIT_PC = 0x0BA,
VHBA_CREATE_ENTRY_PC = 0x0BB,
VHBA_CREATE_FAILURE_PC = 0x0BC,
VHBA_CREATE_EXIT_PC = 0x0BD,
VHBA_CREATE_SUCCESS_PC = 0x0BE,
VHBA_COMMAND_HANDLER_PC = 0x0BF,
VHBA_PROBE_ENTRY_PC = 0x0C0,
VHBA_PROBE_FAILURE_PC = 0x0C1,
VHBA_PROBE_EXIT_PC = 0x0C2,
VNIC_CREATE_ENTRY_PC = 0x0C3,
VNIC_CREATE_FAILURE_PC = 0x0C4,
VNIC_CREATE_SUCCESS_PC = 0x0C5,
VNIC_PROBE_ENTRY_PC = 0x0C6,
VNIC_PROBE_FAILURE_PC = 0x0C7,
VNIC_PROBE_EXIT_PC = 0x0C8,
VPCI_CREATE_ENTRY_PC = 0x0C9,
VPCI_CREATE_FAILURE_PC = 0x0CA,
VPCI_CREATE_EXIT_PC = 0x0CB,
VPCI_PROBE_ENTRY_PC = 0x0CC,
VPCI_PROBE_FAILURE_PC = 0x0CD,
VPCI_PROBE_EXIT_PC = 0x0CE,
CRASH_DEV_ENTRY_PC = 0x0CF,
CRASH_DEV_EXIT_PC = 0x0D0,
CRASH_DEV_HADDR_NULL = 0x0D1,
CRASH_DEV_CONTROLVM_NULL = 0x0D2,
CRASH_DEV_RD_BUS_FAIULRE_PC = 0x0D3,
CRASH_DEV_RD_DEV_FAIULRE_PC = 0x0D4,
CRASH_DEV_BUS_NULL_FAILURE_PC = 0x0D5,
CRASH_DEV_DEV_NULL_FAILURE_PC = 0x0D6,
CRASH_DEV_CTRL_RD_FAILURE_PC = 0x0D7,
CRASH_DEV_COUNT_FAILURE_PC = 0x0D8,
SAVE_MSG_BUS_FAILURE_PC = 0x0D9,
SAVE_MSG_DEV_FAILURE_PC = 0x0DA,
CALLHOME_INIT_FAILURE_PC = 0x0DB
} EVENT_PC;
#ifdef __GNUC__
#define POSTCODE_SEVERITY_ERR DIAG_SEVERITY_ERR
#define POSTCODE_SEVERITY_WARNING DIAG_SEVERITY_WARNING
#define POSTCODE_SEVERITY_INFO DIAG_SEVERITY_PRINT /* TODO-> Info currently
* doesnt show, so we
* set info=warning */
/* example call of POSTCODE_LINUX_2(VISOR_CHIPSET_PC, POSTCODE_SEVERITY_ERR);
* Please also note that the resulting postcode is in hex, so if you are
* searching for the __LINE__ number, convert it first to decimal. The line
* number combined with driver and type of call, will allow you to track down
* exactly what line an error occured on, or where the last driver
* entered/exited from.
*/
/* BASE FUNCTIONS */
#define POSTCODE_LINUX_A(DRIVER_PC, EVENT_PC, pc32bit, severity) \
do { \
unsigned long long post_code_temp; \
post_code_temp = (((U64)DRIVER_PC) << 56) | (((U64)EVENT_PC) << 44) | \
((((U64)__LINE__) & 0xFFF) << 32) | \
(((U64)pc32bit) & 0xFFFFFFFF); \
ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
} while (0)
#define POSTCODE_LINUX_B(DRIVER_PC, EVENT_PC, pc16bit1, pc16bit2, severity) \
do { \
unsigned long long post_code_temp; \
post_code_temp = (((U64)DRIVER_PC) << 56) | (((U64)EVENT_PC) << 44) | \
((((U64)__LINE__) & 0xFFF) << 32) | \
((((U64)pc16bit1) & 0xFFFF) << 16) | \
(((U64)pc16bit2) & 0xFFFF); \
ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
} while (0)
/* MOST COMMON */
#define POSTCODE_LINUX_2(EVENT_PC, severity) \
POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, 0x0000, severity);
#define POSTCODE_LINUX_3(EVENT_PC, pc32bit, severity) \
POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, pc32bit, severity);
#define POSTCODE_LINUX_4(EVENT_PC, pc16bit1, pc16bit2, severity) \
POSTCODE_LINUX_B(CURRENT_FILE_PC, EVENT_PC, pc16bit1, \
pc16bit2, severity);
#endif
#endif
This diff is collapsed.
/* uisthread.h
*
* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/*****************************************************************************/
/* Unisys thread utilities header */
/*****************************************************************************/
#ifndef __UISTHREAD_H__
#define __UISTHREAD_H__
#include "linux/completion.h"
struct uisthread_info {
struct task_struct *task;
int id;
int should_stop;
struct completion has_stopped;
};
/* returns 0 for failure, 1 for success */
int uisthread_start(
struct uisthread_info *thrinfo,
int (*threadfn)(void *),
void *thrcontext,
char *name);
void uisthread_stop(struct uisthread_info *thrinfo);
#endif /* __UISTHREAD_H__ */
This diff is collapsed.
/* vbushelper.h
*
* Copyright 2011 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __VBUSHELPER_H__
#define __VBUSHELPER_H__
#include "vbusdeviceinfo.h"
/* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the
* command line */
#define TARGET_HOSTNAME "linuxguest"
static inline void
BusDeviceInfo_Init(ULTRA_VBUS_DEVICEINFO *pBusDeviceInfo,
const char *deviceType, const char *driverName,
const char *ver, const char *verTag,
const char *buildDate, const char *buildTime)
{
memset(pBusDeviceInfo, 0, sizeof(ULTRA_VBUS_DEVICEINFO));
snprintf(pBusDeviceInfo->devType, sizeof(pBusDeviceInfo->devType),
"%s", (deviceType) ? deviceType : "unknownType");
snprintf(pBusDeviceInfo->drvName, sizeof(pBusDeviceInfo->drvName),
"%s", (driverName) ? driverName : "unknownDriver");
snprintf(pBusDeviceInfo->infoStrings,
sizeof(pBusDeviceInfo->infoStrings), "%s\t%s\t%s %s\t%s",
(ver) ? ver : "unknownVer",
(verTag) ? verTag : "unknownVerTag",
(buildDate) ? buildDate : "noBuildDate",
(buildTime) ? buildTime : "nobuildTime", TARGET_HOSTNAME);
}
#endif
#
# Unisys visorchipset configuration
#
config UNISYS_VISORCHIPSET
tristate "Unisys visorchipset driver"
depends on UNISYSSPAR && UNISYS_VISORUTIL && UNISYS_VISORCHANNEL
---help---
If you say Y here, you will enable the Unisys visorchipset driver.
#
# Makefile for Unisys visorchipset
#
obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset.o
visorchipset-y := visorchipset_main.o controlvm_direct.o file.o filexfer.o \
parser.o
ccflags-y += -Idrivers/staging/unisys/include
ccflags-y += -Idrivers/staging/unisys/uislib
ccflags-y += -Idrivers/staging/unisys/visorchannel
ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
ccflags-y += -Idrivers/staging/unisys/visorutil
ccflags-y += -Iinclude/generated
ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
/* controlvm.h
*
* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __CONTROLVM_H__
#define __CONTROLVM_H__
#include "timskmod.h"
int controlvm_init(void);
void controlvm_deinit(void);
HOSTADDRESS controlvm_get_channel_address(void);
#endif
/* controlvm_direct.c
*
* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/* This is a controlvm-related code that is dependent upon firmware running
* on a virtual partition.
*/
#include "globals.h"
#include "uisutils.h"
#define CURRENT_FILE_PC VISOR_CHIPSET_PC_controlvm_direct_c
/* We can fill in this code when we learn how to make vmcalls... */
int controlvm_init(void)
{
return 0;
}
void controlvm_deinit(void)
{
}
HOSTADDRESS controlvm_get_channel_address(void)
{
static BOOL warned = FALSE;
U64 addr = 0;
U32 size = 0;
if (!VMCALL_SUCCESSFUL(Issue_VMCALL_IO_CONTROLVM_ADDR(&addr, &size))) {
if (!warned) {
ERRDRV("%s - vmcall to determine controlvm channel addr failed",
__func__);
warned = TRUE;
}
return 0;
}
INFODRV("controlvm addr=%Lx", addr);
return addr;
}
/* file.c
*
* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/* This contains the implementation that allows a usermode program to
* communicate with the visorchipset driver using a device/file interface.
*/
#include "globals.h"
#include "visorchannel.h"
#include <linux/mm.h>
#include <linux/fs.h>
#include "uisutils.h"
#define CURRENT_FILE_PC VISOR_CHIPSET_PC_file_c
static struct cdev Cdev;
static VISORCHANNEL **PControlVm_channel;
static dev_t MajorDev = -1; /**< indicates major num for device */
static BOOL Registered = FALSE;
static int visorchipset_open(struct inode *inode, struct file *file);
static int visorchipset_release(struct inode *inode, struct file *file);
static int visorchipset_mmap(struct file *file, struct vm_area_struct *vma);
#ifdef HAVE_UNLOCKED_IOCTL
long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
#else
int visorchipset_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
#endif
static const struct file_operations visorchipset_fops = {
.owner = THIS_MODULE,
.open = visorchipset_open,
.read = NULL,
.write = NULL,
#ifdef HAVE_UNLOCKED_IOCTL
.unlocked_ioctl = visorchipset_ioctl,
#else
.ioctl = visorchipset_ioctl,
#endif
.release = visorchipset_release,
.mmap = visorchipset_mmap,
};
int
visorchipset_file_init(dev_t majorDev, VISORCHANNEL **pControlVm_channel)
{
int rc = -1;
PControlVm_channel = pControlVm_channel;
MajorDev = majorDev;
cdev_init(&Cdev, &visorchipset_fops);
Cdev.owner = THIS_MODULE;
if (MAJOR(MajorDev) == 0) {
/* dynamic major device number registration required */
if (alloc_chrdev_region(&MajorDev, 0, 1, MYDRVNAME) < 0) {
ERRDRV("Unable to allocate+register char device %s",
MYDRVNAME);
RETINT(-1);
}
Registered = TRUE;
INFODRV("New major number %d registered\n", MAJOR(MajorDev));
} else {
/* static major device number registration required */
if (register_chrdev_region(MajorDev, 1, MYDRVNAME) < 0) {
ERRDRV("Unable to register char device %s", MYDRVNAME);
RETINT(-1);
}
Registered = TRUE;
INFODRV("Static major number %d registered\n", MAJOR(MajorDev));
}
if (cdev_add(&Cdev, MKDEV(MAJOR(MajorDev), 0), 1) < 0)
FAIL("failed to create char device", -1);
INFODRV("Registered char device for %s (major=%d)",
MYDRVNAME, MAJOR(MajorDev));
RETINT(0);
Away:
return rc;
}
void
visorchipset_file_cleanup(void)
{
if (Cdev.ops != NULL)
cdev_del(&Cdev);
Cdev.ops = NULL;
if (Registered) {
if (MAJOR(MajorDev) >= 0) {
unregister_chrdev_region(MajorDev, 1);
MajorDev = MKDEV(0, 0);
}
Registered = FALSE;
}
}
static int
visorchipset_open(struct inode *inode, struct file *file)
{
unsigned minor_number = iminor(inode);
int rc = -ENODEV;
DEBUGDRV("%s", __func__);
if (minor_number != 0)
RETINT(-ENODEV);
file->private_data = NULL;
RETINT(0);
Away:
if (rc < 0)
ERRDRV("%s minor=%d failed", __func__, minor_number);
return rc;
}
static int
visorchipset_release(struct inode *inode, struct file *file)
{
int rc = -1;
DEBUGDRV("%s", __func__);
RETINT(0);
Away:
return rc;
}
static int
visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
{
ulong physAddr = 0;
ulong offset = vma->vm_pgoff << PAGE_SHIFT;
GUEST_PHYSICAL_ADDRESS addr = 0;
/* sv_enable_dfp(); */
DEBUGDRV("%s", __func__);
if (offset & (PAGE_SIZE - 1)) {
ERRDRV("%s virtual address NOT page-aligned!", __func__);
return -ENXIO; /* need aligned offsets */
}
switch (offset) {
case VISORCHIPSET_MMAP_CONTROLCHANOFFSET:
vma->vm_flags |= VM_IO;
if (*PControlVm_channel == NULL) {
ERRDRV("%s no controlvm channel yet", __func__);
return -ENXIO;
}
visorchannel_read(*PControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
gpControlChannel), &addr,
sizeof(addr));
if (addr == 0) {
ERRDRV("%s control channel address is 0", __func__);
return -ENXIO;
}
physAddr = (ulong) (addr);
DEBUGDRV("mapping physical address = 0x%lx", physAddr);
if (remap_pfn_range(vma, vma->vm_start,
physAddr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
/*pgprot_noncached */
(vma->vm_page_prot))) {
ERRDRV("%s remap_pfn_range failed", __func__);
return -EAGAIN;
}
break;
default:
return -ENOSYS;
}
DEBUGDRV("%s success!", __func__);
return 0;
}
#ifdef HAVE_UNLOCKED_IOCTL
long
visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#else
int
visorchipset_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
#endif
{
int rc = SUCCESS;
S64 adjustment;
S64 vrtc_offset;
DBGINF("entered visorchipset_ioctl, cmd=%d", cmd);
switch (cmd) {
case VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET:
/* get the physical rtc offset */
vrtc_offset = Issue_VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET();
if (copy_to_user
((void __user *)arg, &vrtc_offset, sizeof(vrtc_offset)))
RETINT(-EFAULT);
DBGINF("insde visorchipset_ioctl, cmd=%d, vrtc_offset=%lld",
cmd, vrtc_offset);
break;
case VMCALL_UPDATE_PHYSICAL_TIME:
if (copy_from_user
(&adjustment, (void __user *)arg, sizeof(adjustment)))
RETINT(-EFAULT);
DBGINF("insde visorchipset_ioctl, cmd=%d, adjustment=%lld", cmd,
adjustment);
rc = Issue_VMCALL_UPDATE_PHYSICAL_TIME(adjustment);
break;
default:
LOGERR("visorchipset_ioctl received invalid command");
RETINT(-EFAULT);
break;
}
RETINT(rc);
Away:
DBGINF("exiting %d!", rc);
return rc;
}
/* file.h
*
* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __FILE_H__
#define __FILE_H__
#include "globals.h"
int visorchipset_file_init(dev_t majorDev, VISORCHANNEL **pControlVm_channel);
void visorchipset_file_cleanup(void);
#endif
This diff is collapsed.
/* filexfer.h
*
* Copyright © 2013 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/* This header file defines the interface that filexfer.c provides to other
* code in the visorchipset driver.
*/
#ifndef __FILEXFER_H__
#define __FILEXFER_H__
#include "globals.h"
#include "controlvmchannel.h"
#include <linux/seq_file.h>
typedef void *(*GET_CONTIGUOUS_CONTROLVM_PAYLOAD_FUNC) (ulong min_size,
ulong max_size,
ulong *actual_size);
typedef BOOL
(*CONTROLVM_RESPOND_WITH_PAYLOAD_FUNC) (CONTROLVM_MESSAGE_HEADER *msgHdr,
u64 fileRequestNumber,
u64 dataSequenceNumber,
int response,
void *bucket, ulong payloadChunkSize,
ulong payloadUsedBytes, BOOL partial);
typedef void
(*TRANSMITFILE_INIT_CONTEXT_FUNC)(void *ctx,
const CONTROLVM_MESSAGE_HEADER *hdr,
u64 file_request_number);
typedef void (*TRANSMITFILE_DUMP_FUNC) (struct seq_file *f, void *ctx,
const char *pfx);
typedef int (*GET_CONTROLVM_FILEDATA_FUNC) (void *ctx,
void *buf, size_t bufsize,
BOOL buf_is_userspace,
size_t *bytes_transferred);
typedef void (*CONTROLVM_RESPOND_FUNC) (void *ctx, int response);
/* Call once to initialize filexfer.o.
* req_context_bytes number of bytes the caller needs to keep track of each file
* transfer conversation. The <ctx_init_value> passed to filexfer_putFile() is
* assumed to be this many bytes in size. Code within filexfer.o will copy this
* into a dynamically-allocated area, and pass back a pointer to that area in
* callback functions.
*/
int filexfer_constructor(size_t req_context_bytes);
/* Call once to clean up filexfer.o */
void filexfer_destructor(void);
/* Call this to dump diagnostic info about all outstanding getFiles/putFiles */
void filexfer_dump(struct seq_file *f);
/* Call to transfer a file from the local filesystem (i.e., from the environment
* where this driver is running) across the controlvm channel to a remote
* environment. 1 or more controlvm responses will be sent as a result, each
* of which whose payload contains file data. Only the last controlvm message
* will have Flags.partialCompletion==0.
*
* msgHdr the controlvm message header of the GETFILE request which
* we just received
* file_request_number this is all data from the GETFILE request that
* uplink_index define which file is to be transferred
* disk_index
* file_name
* get_contiguous_controlvm_payload function to call when space is needed
* in the payload area
* controlvm_respond_with_payload function to call to send each controlvm
* response containing file data as the
* payload; returns FALSE only if the
* payload buffer was freed inline
* dump_func function to dump context data in
* human-readable format
*
* Returns TRUE iff the file transfer request has been successfully initiated,
* or FALSE to indicate failure.
*/
BOOL
filexfer_getFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
u64 file_request_number,
uint uplink_index,
uint disk_index,
char *file_name,
GET_CONTIGUOUS_CONTROLVM_PAYLOAD_FUNC
get_contiguous_controlvm_payload,
CONTROLVM_RESPOND_WITH_PAYLOAD_FUNC
controlvm_respond_with_payload,
TRANSMITFILE_DUMP_FUNC dump_func);
/* Call to create a file in the local filesystem (i.e., in the environment
* where this driver is running) from data received as payload in
* controlvm channel messages from a remote environment. 1 or more controlvm
* messages will be received for this transfer, and only the last will have
* Flags.partialCompletion==0.
*
* msgHdr the controlvm message header of the PUTFILE request which
* we just received
* file_request_number this is all data from the PUTFILE request that
* uplink_index define which file is to be created in the local
* disk_index filesystem
* file_name
* init_context function to call to initialize the
* <req_context_bytes>-sized storage area returned by
* this func; note that it would NOT be sufficient to
* allow the caller to initialize this upon return, as
* the the other user-supplied callbacks might have
* already been called by then
* get_controlvm_filedata function to call to obtain more data for the file
* being written; refer to get_controlvm_filedata()
* in visorchipset_main.c for a complete description
* of parameters
* controlvm_end_putFile function to call to indicate that creation of the
* local file has completed; set <response> to a
* negative value to indicate an error
* dump_func function to dump context data in human-readable
* format
*
* Returns a pointer to a dynamically-allocated storage area of size
* <req_context_bytes> which the caller can use, or NULL for error. The
* caller should NEVER free the returned pointer, but should expect to receive
* it as the <ctx> argument when callback functions are called.
*/
void *filexfer_putFile(CONTROLVM_MESSAGE_HEADER *msgHdr,
u64 file_request_number,
uint uplink_index,
uint disk_index,
char *file_name,
TRANSMITFILE_INIT_CONTEXT_FUNC init_context,
GET_CONTROLVM_FILEDATA_FUNC get_controlvm_filedata,
CONTROLVM_RESPOND_FUNC controlvm_end_putFile,
TRANSMITFILE_DUMP_FUNC dump_func);
#endif
/* globals.h
*
* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __VISORCHIPSET_GLOBALS_H__
#define __VISORCHIPSET_GLOBALS_H__
#include "uniklog.h"
#include "diagnostics/appos_subsystems.h"
#include "timskmod.h"
#include "visorchipset.h"
#include "visorchipset_umode.h"
#include "version.h"
#define MYDRVNAME "visorchipset"
/* module parameters */
extern int visorchipset_testvnic;
extern int visorchipset_testvnicclient;
extern int visorchipset_testmsg;
extern int visorchipset_major;
extern int visorchipset_serverregwait;
extern int visorchipset_clientregwait;
extern int visorchipset_testteardown;
extern int visorchipset_disable_controlvm;
extern int visorchipset_crash_kernel;
extern int visorchipset_holdchipsetready;
#endif
This diff is collapsed.
/* parser.h
*
* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __PARSER_H__
#define __PARSER_H__
#include "uniklog.h"
#include "timskmod.h"
#include "channel.h"
typedef enum {
PARSERSTRING_INITIATOR,
PARSERSTRING_TARGET,
PARSERSTRING_CONNECTION,
PARSERSTRING_NAME,
} PARSER_WHICH_STRING;
typedef struct PARSER_CONTEXT_Tag PARSER_CONTEXT;
PARSER_CONTEXT *parser_init(U64 addr, U32 bytes, BOOL isLocal, BOOL *tryAgain);
PARSER_CONTEXT *parser_init_byteStream(U64 addr, U32 bytes, BOOL isLocal,
BOOL *tryAgain);
void parser_param_start(PARSER_CONTEXT *ctx, PARSER_WHICH_STRING which_string);
void *parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize);
void *parser_string_get(PARSER_CONTEXT *ctx);
GUID parser_id_get(PARSER_CONTEXT *ctx);
char *parser_simpleString_get(PARSER_CONTEXT *ctx);
void *parser_byteStream_get(PARSER_CONTEXT *ctx, ulong *nbytes);
void parser_done(PARSER_CONTEXT *ctx);
#endif
/* testing.h
*
* Copyright 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
#ifndef __VISORCHIPSET_TESTING_H__
#define __VISORCHIPSET_TESTING_H__
#define VISORCHIPSET_TEST_PROC
#include "globals.h"
#include "controlvmchannel.h"
void test_produce_test_message(CONTROLVM_MESSAGE *msg, int isLocalTestAddr);
BOOL test_consume_test_message(CONTROLVM_MESSAGE *msg);
void test_manufacture_vnic_client_add(void *p);
void test_manufacture_vnic_client_add_phys(HOSTADDRESS addr);
void test_manufacture_preamble_messages(void);
void test_manufacture_device_attach(ulong busNo, ulong devNo);
void test_manufacture_device_add(ulong busNo, ulong devNo, GUID dataTypeGuid,
void *pChannel);
void test_manufacture_add_bus(ulong busNo, ulong maxDevices,
GUID id, u8 *name, BOOL isServer);
void test_manufacture_device_destroy(ulong busNo, ulong devNo);
void test_manufacture_bus_destroy(ulong busNo);
void test_manufacture_detach_externalPort(ulong switchNo, ulong externalPortNo);
void test_manufacture_detach_internalPort(ulong switchNo, ulong internalPortNo);
void test_cleanup(void);
#endif
This diff is collapsed.
This diff is collapsed.
/* visorchipset_umode.h
*
* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/** @file *********************************************************************
*
* This describes structures needed for the interface between the
* visorchipset driver and a user-mode component that opens the device.
*
******************************************************************************
*/
#ifndef __VISORCHIPSET_UMODE_H
#define __VISORCHIPSET_UMODE_H
/** The user-mode program can access the control channel buffer directly
* via this memory map.
*/
#define VISORCHIPSET_MMAP_CONTROLCHANOFFSET (0x00000000)
#define VISORCHIPSET_MMAP_CONTROLCHANSIZE (0x00400000) /* 4MB */
#endif /* __VISORCHIPSET_UMODE_H */
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