kvm-guest-drivers-windows

Форк
0
147 строк · 3.9 Кб
1
/*
2
 * This file contains fw_cfg routines
3
 *
4
 * Copyright (C) 2018 Virtuozzo International GmbH
5
 *
6
 */
7
#include "fwcfg.h"
8
#include "trace.h"
9
#include "fwcfg.tmh"
10

11
VOID FWCfgReadBlob(PVOID ioBase, UINT16 key, PVOID buf, ULONG count)
12
{
13
    WRITE_PORT_USHORT((PUSHORT)FW_CFG_CTL(ioBase), key);
14
    READ_PORT_BUFFER_UCHAR(FW_CFG_DAT(ioBase), (PUCHAR)buf, count);
15
}
16

17
NTSTATUS FWCfgCheckSig(PVOID ioBase)
18
{
19
    UCHAR signature[FW_CFG_SIG_SIZE];
20

21
    FWCfgReadBlob(ioBase, FW_CFG_SIGNATURE, signature, FW_CFG_SIG_SIZE);
22
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_ALL,
23
                "Signature is [%.4s]", (PCHAR)signature);
24
    if (memcmp(signature, FW_CFG_QEMU, FW_CFG_SIG_SIZE))
25
    {
26
        TraceEvents(TRACE_LEVEL_ERROR, DBG_ALL, "Signature check failed, "
27
                                                "["FW_CFG_QEMU"] expected");
28
        return STATUS_BAD_DATA;
29
    }
30

31
    return STATUS_SUCCESS;
32
}
33

34
NTSTATUS FWCfgCheckFeatures(PVOID ioBase, UINT32 features)
35
{
36
    UINT32 f_bitmap;
37

38
    FWCfgReadBlob(ioBase, FW_CFG_ID, &f_bitmap, sizeof(f_bitmap));
39
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_ALL, "Features are 0x%lx", f_bitmap);
40
    if ((f_bitmap & features) != features)
41
    {
42
        TraceEvents(TRACE_LEVEL_ERROR, DBG_ALL, "Features check failed, "
43
                                                " 0x%lx expected", features);
44
        return STATUS_BAD_DATA;
45
    }
46

47
    return STATUS_SUCCESS;
48
}
49

50
UINT64 FWCfgReadDmaReg(PVOID ioBase)
51
{
52
    UINT64 dma_reg;
53

54
    ((UINT32 *)&dma_reg)[0] = READ_PORT_ULONG((PULONG)FW_CFG_DMA(ioBase));
55
    ((UINT32 *)&dma_reg)[1] = READ_PORT_ULONG((PULONG)FW_CFG_DMA(ioBase) + 1);
56

57
    return RtlUlonglongByteSwap(dma_reg);
58
}
59

60
VOID FWCfgWriteDmaReg(PVOID ioBase, UINT64 val)
61
{
62
    val = RtlUlonglongByteSwap(val);
63
    WRITE_PORT_ULONG((PULONG)FW_CFG_DMA(ioBase), ((PULONG)&val)[0]);
64
    WRITE_PORT_ULONG((PULONG)FW_CFG_DMA(ioBase) + 1, ((PULONG)&val)[1]);
65
}
66

67
NTSTATUS FWCfgCheckDma(PVOID ioBase)
68
{
69
    UINT64 test = FWCfgReadDmaReg(ioBase);
70
    if (test != FW_CFG_QEMU_DMA)
71
    {
72
        return STATUS_BAD_DATA;
73
    }
74

75
    return STATUS_SUCCESS;
76
}
77

78
/*
79
    At the end of this routine selector points at first file entry
80
*/
81
UINT32 FWCfgGetEntriesNum(PVOID ioBase)
82
{
83
    UINT32 num;
84

85
    FWCfgReadBlob(ioBase, FW_CFG_FILE_DIR, &num, sizeof(num));
86
    num = RtlUlongByteSwap(num);
87
    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_ALL, "Total %lu entries", num);
88

89
    return num;
90
}
91

92
NTSTATUS FWCfgFindEntry(PVOID ioBase, const char *name,
93
                        PUSHORT index, ULONG size)
94
{
95
    UINT32 i;
96
    UINT32 total = FWCfgGetEntriesNum(ioBase);
97
    FWCfgFile f;
98

99
    if (total > MAXUINT16)
100
    {
101
        return STATUS_BAD_DATA;
102
    }
103

104
    for (i = 0; i < total; i++)
105
    {
106
        READ_PORT_BUFFER_UCHAR(FW_CFG_DAT(ioBase), (PUCHAR)&f, sizeof(f));
107
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_ALL, "[%.56s]", f.name);
108
        if (!strncmp(f.name, name, FW_CFG_MAX_FILE_PATH))
109
        {
110
            if (RtlUlongByteSwap(f.size) == size)
111
            {
112
                *index = RtlUshortByteSwap(f.select);
113
                return STATUS_SUCCESS;
114
            }
115
            return STATUS_BAD_DATA;
116
        }
117
    }
118

119
    return STATUS_BAD_DATA;
120
}
121

122
NTSTATUS FWCfgDmaSend(PVOID ioBase, LONGLONG data_pa, USHORT index,
123
                      UINT32 size, FWCfgDmaAccess *pDmaAccess, LONGLONG dmaAccess_pa)
124
{
125
    UINT16 ctrl = FW_CFG_DMA_CTL_SELECT | FW_CFG_DMA_CTL_WRITE;
126
    NTSTATUS status;
127

128
    pDmaAccess->control = RtlUlongByteSwap(((UINT32)index << 16UL) | ctrl);
129
    pDmaAccess->length = RtlUlongByteSwap(size);
130
    pDmaAccess->address = RtlUlonglongByteSwap(data_pa);
131

132
    FWCfgWriteDmaReg(ioBase, (UINT64)dmaAccess_pa);
133

134
    ctrl = RtlUlongByteSwap(pDmaAccess->control) & MAXUINT16;
135
    if (!ctrl)
136
    {
137
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_ALL, "Transfer succeed");
138
        status = STATUS_SUCCESS;
139
    }
140
    else
141
    {
142
        TraceEvents(TRACE_LEVEL_ERROR, DBG_ALL, "Transfer failed, 0x%x", ctrl);
143
        status = STATUS_IO_DEVICE_ERROR;
144
    }
145

146
    return status;
147
}
148

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.