ReactOS 0.4.16-dev-61-ge128cbc
isabus.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: ISA PnP bus register access helpers
5 * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean@protonmail.com>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include "precomp.h"
11
12/* GLOBALS ********************************************************************/
13
15
19
20/* PRIVATE FUNCTIONS **********************************************************/
21
22static
23inline
26 _In_ UCHAR Lfsr,
27 _In_ UCHAR InputBit)
28{
29 UCHAR NextLfsr = Lfsr >> 1;
30
31 NextLfsr |= (((Lfsr ^ NextLfsr) ^ InputBit)) << 7;
32
33 return NextLfsr;
34}
35
36static
37VOID
40{
41 ULONG i;
42
44
45 for (i = 0; i < IsapCardCount; ++i)
46 {
48
49 if (Card->State != IsaWaitForKey)
50 continue;
51
52 /* Reset the LFSR contents */
53 if (Card->Lfsr != Value)
54 {
55 Card->Lfsr = ISAPNP_LFSR_SEED;
56 Card->LfsrCount = 0;
57 continue;
58 }
59
60 /* Generate the next data pattern */
61 Card->Lfsr = IsaBusNextLFSR(Card->Lfsr, 0);
62
63 /* 32 bytes of the initiation key compared correctly */
64 if (++Card->LfsrCount == 32)
65 {
66 Card->State = IsaSleep;
67 }
68 }
69}
70
71static
72VOID
75{
76 ULONG i, j;
77
78 switch (IsapAddressLatch)
79 {
80 case ISAPNP_READPORT:
81 {
82 /* Update the address of the Read Data Port */
83 for (i = 0; i < IsapCardCount; ++i)
84 {
86
87 if (Card->State != IsaIsolation)
88 continue;
89
90 Card->ReadDataPort = (PUCHAR)(((ULONG_PTR)Value << 2) | 3);
91 }
92 break;
93 }
94
96 {
98 {
100 }
101
102 for (i = 0; i < IsapCardCount; ++i)
103 {
105
106 if (Card->State != IsaWaitForKey)
107 {
109 {
110 for (j = 0; j < Card->LogicalDevices; ++j)
111 {
112 PISAPNP_CARD_LOGICAL_DEVICE LogDev = &Card->LogDev[j];
113
114 LogDev->Registers[ISAPNP_ACTIVATE] = 0;
115 }
116 }
118 {
119 Card->SelectNumberReg = 0;
120 }
121 }
123 {
124 Card->State = IsaWaitForKey;
125 }
126 }
127 break;
128 }
129
130 case ISAPNP_WAKE:
131 {
132 for (i = 0; i < IsapCardCount; ++i)
133 {
135
136 if (Card->State == IsaWaitForKey)
137 continue;
138
139 if (Card->SelectNumberReg != Value)
140 {
141 if (Card->State == IsaConfgure || Card->State == IsaIsolation)
142 {
143 Card->State = IsaSleep;
144
145 if (IsapConfigureCard == Card)
146 {
148 }
149 }
150
151 continue;
152 }
153
154 Card->RomIdx = 0;
155 Card->SerialIsolationIdx = 0;
156
157 if (Card->State == IsaSleep)
158 {
159 if (Value == 0)
160 {
161 Card->State = IsaIsolation;
162
163 Card->IsolationRead = 0;
164 }
165 else
166 {
167 Card->State = IsaConfgure;
168
169 /* Only one card can be in the configure state */
171 }
172 }
173 }
174
175 break;
176 }
177
179 {
180 ULONG CsnAssigned = 0;
181
182 /* Assign the CSN */
183 for (i = 0; i < IsapCardCount; ++i)
184 {
186
187 if (Card->State != IsaIsolation)
188 continue;
189
190 ok(Value != 0, "The new CSN is zero\n");
191 ok(Card->SelectNumberReg != Value, "CSNs must be assigned sequentially");
192
193 Card->State = IsaConfgure;
194 Card->SelectNumberReg = Value;
195
196 /* Only one card can be in the configure state */
198
199 ++CsnAssigned;
200 ok_eq_ulong(CsnAssigned, 1UL);
201 }
202 break;
203 }
204
206 {
207 ok(IsapConfigureCard != NULL, "Invalid write to a LDN register\n");
208
209 if (IsapConfigureCard != NULL)
210 {
211 ok(IsapConfigureCard->LogicalDevices != 0, "Write to a read-only register\n");
212 ok(Value < IsapConfigureCard->LogicalDevices, "Invalid write to a LDN register\n");
213
215 }
216 break;
217 }
218
219 case ISAPNP_ACTIVATE:
220 {
221 Value &= 0x01;
222 goto WriteDeviceRegister;
223 }
224
226 {
227 Value &= 0x03;
228 goto WriteDeviceRegister;
229 }
230
233 case ISAPNP_STATUS:
234 {
235 ok(FALSE, "Write to a read-only register %02x\n", IsapAddressLatch);
236 break;
237 }
238
239 default:
240 {
241 if (IsapAddressLatch >= 0x40)
242 {
244
245WriteDeviceRegister:
246 ok(IsapConfigureCard != NULL, "Invalid write to device register\n");
247
248 if (IsapConfigureCard != NULL)
249 {
251
253 }
254 }
255 else
256 {
257 ok(FALSE, "Unexpected write to register %02x\n", IsapAddressLatch);
258 }
259 break;
260 }
261 }
262}
263
264static
265UCHAR
268{
269 ULONG i, ResponseMap = 0, ListenMap = 0;
270 UCHAR Result = 0xFF;
271
272 for (i = 0; i < IsapCardCount; ++i)
273 {
275
276 if (Card->State != IsaIsolation || Card->ReadDataPort != Port)
277 continue;
278
279 /* The hardware on each card expects 72 pairs of reads */
280 if (Card->SerialIsolationIdx == RTL_BITS_OF(ISAPNP_IDENTIFIER))
281 continue;
282
283 Card->IsolationRead ^= 1;
284
285 if (Card->IsolationRead)
286 {
287 if (Card->PnpRom[Card->SerialIsolationIdx / 8] & (1 << (Card->SerialIsolationIdx % 8)))
288 Card->SerialIdResponse = 0x55;
289 else
290 Card->SerialIdResponse = 0x00;
291
292 ++Card->RomIdx;
293 ++Card->SerialIsolationIdx;
294 }
295 else
296 {
297 Card->SerialIdResponse <<= 1;
298
299 if (Card->SerialIdResponse == 0xAA)
300 ResponseMap |= (1 << i);
301 else
302 ListenMap |= (1 << i);
303 }
304
305 if ((Card->SerialIdResponse > Result) || (Result == 0xFF))
306 Result = Card->SerialIdResponse;
307 }
308
309 /* Release passive cards from the isolation state */
310 if (ResponseMap != 0 && ListenMap != 0)
311 {
312 for (i = 0; i < RTL_BITS_OF(ListenMap); ++i)
313 {
314 if (ListenMap & (1 << i))
315 {
317
318 Card->State = IsaSleep;
319 }
320 }
321 }
322
323 return Result;
324}
325
326static
327UCHAR
330{
333
335 return 0xFF;
336
337 switch (IsapAddressLatch)
338 {
340 {
342 break;
343
344 /* The resource data register may return an invalid identifier checksum byte */
346 {
348 break;
349 }
350
352 }
353
354 case ISAPNP_STATUS:
355 return 0x01; /* Resource data byte available */
356
359
362
363 case ISAPNP_ACTIVATE:
365 goto ReadDeviceRegister;
366
367 default:
368 {
369 if (IsapAddressLatch >= 0x40)
370 {
372
373ReadDeviceRegister:
375
376 return LogDev->Registers[IsapAddressLatch];
377 }
378 else
379 {
380 ok(FALSE, "Unexpected read from register %02x\n", IsapAddressLatch);
381 }
382 break;
383 }
384 }
385
386 return 0xFF;
387}
388
389static
390UCHAR
393{
394 UCHAR i, j, Lfsr;
395
396 Lfsr = ISAPNP_LFSR_SEED;
397 for (i = 0; i < FIELD_OFFSET(ISAPNP_IDENTIFIER, Checksum); ++i)
398 {
400
401 for (j = 0; j < RTL_BITS_OF(Byte); ++j)
402 {
403 Lfsr = IsaBusNextLFSR(Lfsr, Byte);
404 Byte >>= 1;
405 }
406 }
407
408 return Lfsr;
409}
410
411static
412UCHAR
414 _In_ PUCHAR PnpRom,
415 _In_ ULONG RomSize)
416{
418 UNREFERENCED_PARAMETER(RomSize);
419
420 /* This means "Checksummed properly" */
421 return 0x00;
422}
423
424static
425VOID
428{
429 Card->State = IsaWaitForKey;
430 Card->Lfsr = ISAPNP_LFSR_SEED;
431 Card->LfsrCount = 0;
432 Card->SelectNumberReg = 0;
433 Card->ReadDataPort = NULL;
434}
435
436/* PUBLIC FUNCTIONS ***********************************************************/
437
438VOID
441 _In_ PVOID PnpRom,
442 _In_ ULONG RomSize,
443 _In_ ULONG LogicalDevices)
444{
445 Card->RomSize = RomSize;
446 Card->PnpRom = PnpRom;
447 Card->PnpRom[FIELD_OFFSET(ISAPNP_IDENTIFIER, Checksum)] = IsaBusPnpChecksum(PnpRom);
448 Card->PnpRom[RomSize - 1] = IsaBusResourceDataChecksum(PnpRom, RomSize);
449 Card->LogicalDevices = LogicalDevices;
450
452
454}
455
456VOID
457NTAPI
461{
462 switch ((ULONG_PTR)Port)
463 {
464 case 0x279:
466 break;
467
468 case 0xA79:
470 break;
471
472 default:
473 ok(FALSE, "Unexpected write to port %p %02x\n", Port, Value);
474 break;
475 }
476}
477
478UCHAR
479NTAPI
482{
484
485 /* We can write only to NT Read Data Ports */
486 switch ((ULONG_PTR)Port)
487 {
488 case 0x2F4 | 3:
490 break;
491
492 /* Indicate that the Read Data Port is in conflict */
493 case 0x274 | 3:
494 case 0x3E4 | 3:
495 case 0x204 | 3:
496 case 0x2E4 | 3:
497 case 0x354 | 3:
498 Result = 0x00;
499 break;
500
501 default:
502 ok(FALSE, "Unexpected read from port %p\n", Port);
503 Result = 0xFF;
504 break;
505 }
506
507 return Result;
508}
#define ok_eq_ulong(value, expected)
Definition: apitest.h:63
@ Identifier
Definition: asmpp.cpp:95
#define ok(value,...)
Definition: atltest.h:57
Definition: card.h:28
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
unsigned char Byte
Definition: zlib.h:37
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
CPPORT Port[4]
Definition: headless.c:35
#define ISAPNP_IORANGECHECK
Definition: isapnphw.h:34
#define ISAPNP_LFSR_SEED
Definition: isapnphw.h:58
#define ISAPNP_CONFIG_RESET
Definition: isapnphw.h:54
#define ISAPNP_LOGICALDEVICENUMBER
Definition: isapnphw.h:31
#define ISAPNP_SERIALISOLATION
Definition: isapnphw.h:25
#define ISAPNP_ACTIVATE
Definition: isapnphw.h:33
#define ISAPNP_RESOURCEDATA
Definition: isapnphw.h:28
#define ISAPNP_READPORT
Definition: isapnphw.h:24
#define ISAPNP_WAKE
Definition: isapnphw.h:27
#define ISAPNP_STATUS
Definition: isapnphw.h:29
#define ISAPNP_CARDSELECTNUMBER
Definition: isapnphw.h:30
#define ISAPNP_CONFIG_WAIT_FOR_KEY
Definition: isapnphw.h:55
#define ISAPNP_CONFIGCONTROL
Definition: isapnphw.h:26
#define ISAPNP_CONFIG_RESET_CSN
Definition: isapnphw.h:56
PISAPNP_CARD IsapCard
Definition: isabus.c:14
static UCHAR IsaBusNextLFSR(_In_ UCHAR Lfsr, _In_ UCHAR InputBit)
Definition: isabus.c:25
static VOID IsaBusPlugInCard(_Inout_ PISAPNP_CARD Card)
Definition: isabus.c:426
static UCHAR IsaBusPnpChecksum(_In_ PISAPNP_IDENTIFIER Identifier)
Definition: isabus.c:391
static UCHAR IsaBusReadDataPortRegister(_In_ PUCHAR Port)
Definition: isabus.c:328
VOID IsaBusCreateCard(_Inout_ PISAPNP_CARD Card, _In_ PVOID PnpRom, _In_ ULONG RomSize, _In_ ULONG LogicalDevices)
Definition: isabus.c:439
static PISAPNP_CARD IsapConfigureCard
Definition: isabus.c:16
static VOID IsaBusWriteDataRegister(_In_ UCHAR Value)
Definition: isabus.c:73
static UCHAR IsaBusResourceDataChecksum(_In_ PUCHAR PnpRom, _In_ ULONG RomSize)
Definition: isabus.c:413
static ULONG IsapCardCount
Definition: isabus.c:17
static UCHAR IsaBusReadSerialIsolationRegister(_In_ PUCHAR Port)
Definition: isabus.c:266
static VOID IsaBusWriteAddressRegister(_In_ UCHAR Value)
Definition: isabus.c:38
static UCHAR IsapAddressLatch
Definition: isabus.c:18
@ IsaSleep
Definition: precomp.h:103
@ IsaConfgure
Definition: precomp.h:105
@ IsaIsolation
Definition: precomp.h:104
@ IsaWaitForKey
Definition: precomp.h:102
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define RTL_BITS_OF(sizeOfArg)
Definition: ntbasedef.h:668
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
ISAPNP_CARD_LOGICAL_DEVICE LogDev[TEST_MAX_SUPPORTED_DEVICES]
Definition: precomp.h:130
PUCHAR ReadDataPort
Definition: precomp.h:126
ULONG LogicalDevices
Definition: precomp.h:129
UCHAR DeviceNumberReg
Definition: precomp.h:121
ULONG RomSize
Definition: precomp.h:128
ULONG RomIdx
Definition: precomp.h:127
PUCHAR PnpRom
Definition: precomp.h:125
UCHAR SelectNumberReg
Definition: precomp.h:120
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
unsigned char UCHAR
Definition: xmlstorage.h:181