ReactOS 0.4.16-dev-1369-gd4d04c8
HalPortIo.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel-Mode Tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Tests for string I/O intrinsic functions
5 * COPYRIGHT: Copyright 2025 Dmitry Borisov <di.sean@protonmail.com>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include <kmt_test.h>
11
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS ********************************************************************/
16
17/* Compile with the highest optimization level to trigger a bug (See CORE-20078) */
18#ifdef _MSC_VER
19#pragma optimize("gst", on)
20#pragma auto_inline(on)
21#else
22#pragma GCC optimize("O3")
23#endif
24
25/* Used to isolate the effects of intrinsics from each other */
26typedef struct _TEST_CONTEXT
27{
34
35/* TEST FUNCTIONS *************************************************************/
36
37static
38/*
39 * Isolate the effects of intrinsics from each other
40 * and hide the TEST_CONTEXT initialization from the optimizer.
41 */
43VOID
46{
47 __outwordstring(Context->Port, Context->Buffer, Context->Size / sizeof(USHORT));
48
49 /*
50 * The 'rep outsw' instruction increments or decrements the address in ESI by Size * 2.
51 * Test for CORE-20078: the ESI value should be preserved across calls.
52 */
53 ok_eq_pointer(Context->Buffer, Context->OldBuffer);
54}
55
56static
58VOID
61{
62 __outdwordstring(Context->Port, Context->Buffer, Context->Size / sizeof(ULONG));
63
64 ok_eq_pointer(Context->Buffer, Context->OldBuffer);
65}
66
67static
69VOID
72{
73 __inbytestring(Context->Port, Context->Buffer, Context->Size);
74
75 ok_eq_pointer(Context->Buffer, Context->OldBuffer);
76}
77
78static
80VOID
83{
84 __inwordstring(Context->Port, Context->Buffer, Context->Size / sizeof(USHORT));
85
86 ok_eq_pointer(Context->Buffer, Context->OldBuffer);
87}
88
89static
91VOID
94{
95 __outdwordstring(Context->Port, Context->Buffer, Context->Size / sizeof(ULONG));
96
97 ok_eq_pointer(Context->Buffer, Context->OldBuffer);
98}
99
100static
102VOID
105{
106 __inbytestring(Context->Port, Context->Buffer, Context->Size);
107
108 ok_eq_pointer(Context->Buffer, Context->OldBuffer);
109}
110
111static
112VOID
114{
116 UCHAR Buffer[20];
117
118 /* End of the x86 I/O range */
119 Context.Port = 0xFFFF - sizeof(ULONG);
120
121 Context.Buffer = Buffer;
122 Context.OldBuffer = Buffer;
123 Context.Size = sizeof(Buffer);
124
128
129 /*
130 * Check whether the driver is running inside a virtual machine
131 * as it's not safe to write to I/O ports
132 * without having the port resources assigned.
133 */
134 if (!skip(KmtIsVirtualMachine, "Please run those tests in a supported virtual machine\n"))
135 {
139 }
140}
141
142START_TEST(HalPortIo)
143{
144 TestStringIo();
145}
struct _TEST_CONTEXT TEST_CONTEXT
static DECLSPEC_NOINLINE VOID TestWriteStringUshort(_In_ PTEST_CONTEXT Context)
Definition: HalPortIo.c:44
static DECLSPEC_NOINLINE VOID TestReadStringUlong(_In_ PTEST_CONTEXT Context)
Definition: HalPortIo.c:92
static DECLSPEC_NOINLINE VOID TestWriteStringUchar(_In_ PTEST_CONTEXT Context)
Definition: HalPortIo.c:70
static DECLSPEC_NOINLINE VOID TestWriteStringUlong(_In_ PTEST_CONTEXT Context)
Definition: HalPortIo.c:59
static VOID TestStringIo(VOID)
Definition: HalPortIo.c:113
struct _TEST_CONTEXT * PTEST_CONTEXT
static DECLSPEC_NOINLINE VOID TestReadStringUshort(_In_ PTEST_CONTEXT Context)
Definition: HalPortIo.c:81
static DECLSPEC_NOINLINE VOID TestReadStringUchar(_In_ PTEST_CONTEXT Context)
Definition: HalPortIo.c:103
#define ok_eq_pointer(value, expected)
Definition: apitest.h:40
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
Definition: bufpool.h:45
PPC_QUAL void __outwordstring(unsigned long const Port, const unsigned short *const Buffer, const unsigned long Count)
Definition: intrin_ppc.h:662
PPC_QUAL void __inwordstring(unsigned long Port, unsigned short *Buffer, unsigned long Count)
Definition: intrin_ppc.h:591
PPC_QUAL void __inbytestring(unsigned long Port, unsigned char *Buffer, unsigned long Count)
Definition: intrin_ppc.h:584
PPC_QUAL void __outdwordstring(unsigned long const Port, const unsigned long *const Buffer, const unsigned long Count)
Definition: intrin_ppc.h:671
BOOLEAN KmtIsVirtualMachine
#define _In_
Definition: no_sal2.h:158
#define DECLSPEC_NOINLINE
Definition: ntbasedef.h:229
unsigned short USHORT
Definition: pedump.c:61
USHORT Port
Definition: HalPortIo.c:30
PVOID Buffer
Definition: HalPortIo.c:32
ULONG Size
Definition: HalPortIo.c:31
UCHAR Pad[78]
Definition: HalPortIo.c:29
PVOID OldBuffer
Definition: HalPortIo.c:28
uint32_t ULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: xmlstorage.h:181