reactos/modules/rostests/unittests/isapnp/res_card.c

1339 lines
39 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS API Tests
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Dummy card resource tests for the ISA PnP bus driver
* COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean@protonmail.com>
*/
/* INCLUDES *******************************************************************/
#include "precomp.h"
/* GLOBALS ********************************************************************/
static UCHAR DrvpTestPnpRom[] =
{
0x49, 0xF3, // Vendor ID 0xF349 'ROS'
0x12, 0x34, // Product ID 0x1234
0xFF, 0xFF, 0xFF, 0xFF, // Serial Number
0xFF, // Checksum (dummy)
0x0A, 0x10, 0x10, // PnP version 1.0, vendor version 1.0
0x82, 6, 0x00, // ANSI identifier 'Test 1'
'T', 'e', 's', 't', ' ', '1',
/* ********************* DEVICE 1 ********************* */
0x15, // Logical device ID
0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS'
0x12, 0x34, // Product ID 0x1234
0x00,
0x82, 12, 0x00, // ANSI identifier 'Test 1 Dev 1'
'T', 'e', 's', 't', ' ', '1', ' ',
'D', 'e', 'v', ' ', '1',
// (A) Fixed
// (B) Dependent
// (C) Fixed
// (D) End
0x47, 0x01, 0x30, 0x03, 0x40, 0x03, 0x04, 0x02, // I/O Base 16-bit 0x330-0x340, len 2, align 4
0x30, // Start dependent Function
0x47, 0x00, 0x00, 0x06, 0x80, 0x07, 0x01, 0x08, // I/O Base 10-bit 0x600-0x780, len 8, align 1
0x4B, 0x16, 0xFC, 0x0C, // Fixed I/O 0x16, length 12 (NOTE: We fill byte 2 with garbage)
0x22, 0x20, 0x00, // IRQ 5 positive edge triggered
0x23, 0x1C, 0x00, 0x08, // IRQ 2, 3, 4 active low, level-sensitive
0x31, 0x02, // Start dependent Function
0x81, 0x09, 0x00, // Memory Range
0x1B, // Writeable, read-cacheable, write-through, supports range length, 32-bit memory only
0x80, 0x0C, // Range minimum 0xC8000
0xC0, 0x0D, // Range maximum 0xDC000
0x40, 0xFF, // Base alignment 0xFF40
0x40, 0x00, // Range length 0x4000
0x81, 0x09, 0x00, // Memory Range
0x66, // Non-writeable, read-cacheable, write-through,
// supports high address, 8-bit, shadowable, expansion ROM
0x40, 0x0D, // Range minimum 0xD4000
0x80, 0x0D, // Range maximum 0xD8000
0x00, 0x00, // Base alignment 0x10000 (NOTE: Special case)
0x40, 0x00, // Range length 0x4000
0x2A, 0x03, 0x04, // DMA 0 or 1. 8-bit only, ISA Master, not use count by byte/word, ISA compat
0x38, // End dependent Function
0x2A, 0x04, 0x41, // DMA 3. 8- and 16-bit, not use count by byte/word, Type B
/* ********************* DEVICE 2 ********************* */
0x15, // Logical device ID
0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS'
0x12, 0x35, // Product ID 0x1235
0x00,
// (A) Fixed
// (B) Dependent
// (C) End
0x47, 0x01, 0x00, 0x05, 0x06, 0x05, 0x01, 0x01, // I/O Base 16-bit 0x500-0x506, len 1, align 1
0x30, // Start dependent Function
0x47, 0x01, 0x00, 0x06, 0x07, 0x06, 0x01, 0x01, // I/O Base 16-bit 0x600-0x607, len 1, align 1
0x30, // Start dependent Function
0x47, 0x01, 0x00, 0x07, 0x08, 0x07, 0x01, 0x01, // I/O Base 16-bit 0x700-0x708, len 1, align 1
0x38, // End dependent Function
/* ********************* DEVICE 3 ********************* */
0x15, // Logical device ID
0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS'
0x12, 0x36, // Product ID 0x1236
0x00,
// (A) Dependent
// (B) Fixed
// (C) End
0x30, // Start dependent Function
0x47, 0x01, 0x00, 0x06, 0x07, 0x06, 0x01, 0x01, // I/O Base 16-bit 0x600-0x607, len 1, align 1
0x30, // Start dependent Function
0x47, 0x01, 0x00, 0x07, 0x08, 0x07, 0x01, 0x01, // I/O Base 16-bit 0x700-0x708, len 1, align 1
0x38, // End dependent Function
0x47, 0x01, 0x00, 0x05, 0x06, 0x05, 0x01, 0x01, // I/O Base 16-bit 0x500-0x506, len 1, align 1
/* ********************* DEVICE 4 ********************* */
0x15, // Logical device ID
0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS'
0x12, 0x36, // Product ID 0x1236
0x00,
// (A) Dependent
// (B) End
0x30, // Start dependent Function
0x47, 0x01, 0x00, 0x06, 0x07, 0x06, 0x01, 0x01, // I/O Base 16-bit 0x600-0x607, len 1, align 1
0x30, // Start dependent Function
0x47, 0x01, 0x00, 0x07, 0x08, 0x07, 0x01, 0x01, // I/O Base 16-bit 0x700-0x708, len 1, align 1
0x38, // End dependent Function
/* ********************* DEVICE 5 ********************* */
// We cannot mix 24- and 32-bit memory descriptors, so create a separate logical device
0x15, // Logical device ID
0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS'
0xAB, 0xCD, // Product ID 0xABCD
0x00,
0x1C, // Compatible device ID
0xAD, 0x34, // Vendor ID 0x34AD 'MEM'
0x56, 0x78, // Product ID 0x5678
0x82, 12, 0x00, // ANSI identifier 'Test 1 Dev 2'
'T', 'e', 's', 't', ' ', '1', ' ',
'D', 'e', 'v', ' ', '2',
// (A) Fixed
// (B) End
0x85, 0x11, 0x00, // 32-bit Memory Range
0x66, // Non-writeable, read-cacheable, write-through,
// supports high address, 8-bit, shadowable, expansion ROM
0x00, 0x00, 0x0D, 0x00, // Range minimum 0xD0000
0x00, 0x00, 0x0E, 0x00, // Range maximum 0xE0000
0x00, 0x01, 0x00, 0x00, // Base alignment 0x100
0x00, 0x80, 0x00, 0x00, // Range length 0x8000
0x86, 0x09, 0x00, // 32-bit Fixed Memory Range
0x66, // Non-writeable, read-cacheable, write-through,
// supports high address, 8-bit, shadowable, expansion ROM
0x00, 0x80, 0x0C, 0x00, // Range base address 0xC8000
0x00, 0x80, 0x00, 0x00, // Length 0x008000
/* ********************* DEVICE 6 ********************* */
0x15, // Logical device ID
0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS'
0xA0, 0x01, // Product ID 0xA001
0x00,
// NOTE: We don't supply any ANSI identifiers here
0x81, 0x09, 0x00, // Memory Range
0x6E, // Non-writeable, read-cacheable, write-through,
// supports high address, 16-bit, shadowable, expansion ROM
0x00, 0x0A, // Range minimum 0xA0000
0x40, 0x0A, // Range maximum 0xA4000
0x04, 0x00, // Base alignment 4
0x10, 0x00, // Range length 0x1000
0x81, 0x09, 0x00, // Memory Range
0x66, // Non-writeable, read-cacheable, write-through,
// supports high address, 8-bit, shadowable, expansion ROM
0x00, 0x08, // Range minimum 0x8000
0x00, 0x09, // Range maximum 0x9000
0x04, 0x00, // Base alignment 4
0x01, 0x00, // Range length 0x100
0x2A, 0x40, 0x04, // DMA 6
0x22, 0x20, 0x00, // IRQ 5 positive edge triggered
0x4B, 0x80, 0x00, 0x08, // Fixed I/O 0x80, length 8
/* ********************* DEVICE 7 ********************* */
0x15, // Logical device ID
0xB0, 0x15, // Vendor ID 0x15B0 'EMP'
0x20, 0x00, // Product ID 0x2000
0x00,
// No resource requirements for this device
0x73, '1', '2', '3', // Vendor defined valid tag
/* **************************************************** */
0x79, // END
0xFF, // Checksum (dummy)
};
/* FUNCTIONS ******************************************************************/
VOID
DrvCreateCard1(
_In_ PISAPNP_CARD Card)
{
PISAPNP_CARD_LOGICAL_DEVICE LogDev;
IsaBusCreateCard(Card, DrvpTestPnpRom, sizeof(DrvpTestPnpRom), 7);
/* NOTE: Boot resources of the devices should be made from the requirements */
/* ********************* DEVICE 1 ********************* */
LogDev = &Card->LogDev[0];
/*
* Assign some I/O base but don't enable decodes.
* The driver will ignore such I/O configuration.
*/
LogDev->Registers[0x60] = 0x03;
LogDev->Registers[0x61] = 0x90;
/* ******************* DEVICE 2, 3, 4 ***************** */
LogDev++;
LogDev++;
LogDev++;
/* ********************* DEVICE 5 ********************* */
LogDev++;
/* Enable decodes */
LogDev->Registers[0x30] = 0x01;
/* No DMA is active */
LogDev->Registers[0x74] = 0x04;
LogDev->Registers[0x75] = 0x04;
/* Memory 32 Base #0 0xD6000 */
LogDev->Registers[0x76] = 0x00;
LogDev->Registers[0x77] = 0x0D;
LogDev->Registers[0x78] = 0x60;
LogDev->Registers[0x79] = 0x00;
/* Memory 32 Control #0 - enable range length, 8-bit memory */
LogDev->Registers[0x7A] = 0x00;
/* Memory 32 Range length #0 0xFFFF8000 (32kB) */
LogDev->Registers[0x7B] = 0xFF;
LogDev->Registers[0x7C] = 0xFF;
LogDev->Registers[0x7D] = 0x80;
LogDev->Registers[0x7E] = 0x00;
/* Memory 32 Base #1 0xC8000 */
LogDev->Registers[0x80] = 0x00;
LogDev->Registers[0x81] = 0x0C;
LogDev->Registers[0x82] = 0x80;
LogDev->Registers[0x83] = 0x00;
/* Memory 32 Control #1 - enable upper limit, 8-bit memory */
LogDev->Registers[0x84] = 0x01;
/* Memory 32 Limit #1 0xD0000 (0xC8000 + 0x8000 = 0xD0000) */
LogDev->Registers[0x85] = 0x00;
LogDev->Registers[0x86] = 0x0D;
LogDev->Registers[0x87] = 0x00;
LogDev->Registers[0x88] = 0x00;
/* ********************* DEVICE 6 ********************* */
LogDev++;
/* Enable decodes */
LogDev->Registers[0x30] = 0x01;
/* Memory Base #0 0xA0000 */
LogDev->Registers[0x40] = 0x0A;
LogDev->Registers[0x41] = 0x00;
/*
* Memory Control #0 - enable upper limit, 8-bit memory.
* The resource descriptor is 16-bit,
* so we can test the configuration code that touches this register.
*/
LogDev->Registers[0x42] = 0x01;
/* Memory Limit #0 0xA4000 (0xA0000 + 0x4000 = 0xA4000) */
LogDev->Registers[0x43] = 0x0A;
LogDev->Registers[0x44] = 0x40;
/* Memory Control #1 - enable range length, 8-bit memory */
LogDev->Registers[0x4A] = 0x00;
/* Memory Base #1 is disabled */
/* I/O Base 80 */
LogDev->Registers[0x60] = 0x00;
LogDev->Registers[0x61] = 0x80;
/* IRQ 5 low-to-high transition */
LogDev->Registers[0x70] = 0x05 | 0xF0; // We add some garbage, must be ignored by the driver
LogDev->Registers[0x71] = 0x02;
/* DMA 6 */
LogDev->Registers[0x74] = 0x06 | 0xF8; // Ditto
/* No DMA is active */
LogDev->Registers[0x75] = 0x04;
/* ********************* DEVICE 7 ********************* */
/* No resources on purpose */
}
/* No boot resources */
static
VOID
DrvTestCard1Dev1QueryResources(
_In_ PCM_RESOURCE_LIST ResourceList)
{
ok_eq_pointer(ResourceList, NULL);
}
/*
* Interface 1 Bus 0 Slot 0 AlternativeLists 2
*
* AltList 0, AltList->Count 8 Ver.1 Rev.30
* [0:1:11] IO: Min 0:330, Max 0:341, Align 4 Len 2
* [0:1:5] IO: Min 0:600, Max 0:787, Align 1 Len 8
* [0:1:5] IO: Min 0:16, Max 0:21, Align 1 Len C
* [0:1:1] INT: Min 5 Max 5
* [0:1:1] INT: Min 2 Max 2
* [8:1:1] INT: Min 3 Max 3
* [8:1:1] INT: Min 4 Max 4
* [0:0:0] DMA: Min 2 Max 2
*
* AltList 1, AltList->Count 6 Ver.1 Rev.31
* [0:1:11] IO: Min 0:330, Max 0:341, Align 4 Len 2
* [0:1:10] MEM: Min 0:C8000, Max 0:DFFFF, Align FF40 Len 4000
* [0:1:10] MEM: Min 0:D4000, Max 0:DBFFF, Align 10000 Len 4000
* [0:0:0] DMA: Min 0 Max 0
* [8:0:0] DMA: Min 1 Max 1
* [0:0:0] DMA: Min 2 Max 2
*/
static
VOID
DrvTestCard1Dev1QueryResourceRequirements(
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
PIO_RESOURCE_DESCRIPTOR Descriptor;
PIO_RESOURCE_LIST AltList;
ok(ReqList != NULL, "ReqList is NULL\n");
if (ReqList == NULL)
{
skip("No ReqList\n");
return;
}
expect_requirements_list_header(ReqList, Isa, 2UL);
/************************* LIST 0 ************************/
AltList = &ReqList->List[0];
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 8UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
2ul,
4ul,
0x330ull,
0x341ull);
Descriptor++;
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE,
CmResourceShareDeviceExclusive,
8ul,
1ul,
0x600ull,
0x787ull);
Descriptor++;
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE,
CmResourceShareDeviceExclusive,
12ul,
1ul,
0x16ull,
0x21ull);
Descriptor++;
expect_irq_req(Descriptor,
0,
CM_RESOURCE_INTERRUPT_LATCHED,
CmResourceShareDeviceExclusive,
5ul,
5ul);
Descriptor++;
// NOTE: The native driver returns CM_RESOURCE_INTERRUPT_LATCHED
// and CmResourceShareDeviceExclusive for some reason
#if 0
expect_irq_req(Descriptor,
0,
CM_RESOURCE_INTERRUPT_LATCHED,
CmResourceShareDeviceExclusive,
2ul,
2ul);
#else
expect_irq_req(Descriptor,
0,
CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE,
CmResourceShareShared,
2ul,
2ul);
#endif
Descriptor++;
#if 0
expect_irq_req(Descriptor,
IO_RESOURCE_ALTERNATIVE,
CM_RESOURCE_INTERRUPT_LATCHED,
CmResourceShareDeviceExclusive,
3ul,
3ul);
#else
expect_irq_req(Descriptor,
IO_RESOURCE_ALTERNATIVE,
CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE,
CmResourceShareShared,
3ul,
3ul);
#endif
Descriptor++;
#if 0
expect_irq_req(Descriptor,
IO_RESOURCE_ALTERNATIVE,
CM_RESOURCE_INTERRUPT_LATCHED,
CmResourceShareDeviceExclusive,
4ul,
4ul);
#else
expect_irq_req(Descriptor,
IO_RESOURCE_ALTERNATIVE,
CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE,
CmResourceShareShared,
4ul,
4ul);
#endif
Descriptor++;
expect_dma_req(Descriptor,
0,
CM_RESOURCE_DMA_8,
CmResourceShareUndetermined,
2ul,
2ul);
Descriptor++;
/************************* LIST 1 ************************/
AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count);
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 6UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
2ul,
4ul,
0x330ull,
0x341ull);
Descriptor++;
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24,
CmResourceShareDeviceExclusive,
0x4000ul,
0xFF40ul,
0xC8000ull,
0xDFFFFull);
Descriptor++;
// NOTE: The native driver returns CM_RESOURCE_MEMORY_24 only for some reason
#if 0
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24,
CmResourceShareDeviceExclusive,
0x4000ul,
0x10000ul,
0xD4000ull,
0xDBFFFull);
#else
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x4000ul,
0x10000ul,
0xD4000ull,
0xDBFFFull);
#endif
Descriptor++;
expect_dma_req(Descriptor,
0,
CM_RESOURCE_DMA_8,
CmResourceShareUndetermined,
0ul,
0ul);
Descriptor++;
expect_dma_req(Descriptor,
IO_RESOURCE_ALTERNATIVE,
CM_RESOURCE_DMA_8,
CmResourceShareUndetermined,
1ul,
1ul);
Descriptor++;
expect_dma_req(Descriptor,
0,
CM_RESOURCE_DMA_8,
CmResourceShareUndetermined,
2ul,
2ul);
Descriptor++;
/*********************************************************/
ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList));
ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList);
}
VOID
DrvTestCard1Dev1Resources(
_In_ PCM_RESOURCE_LIST ResourceList,
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
DrvTestCard1Dev1QueryResources(ResourceList);
DrvTestCard1Dev1QueryResourceRequirements(ReqList);
}
/* No boot resources */
static
VOID
DrvTestCard1Dev2QueryResources(
_In_ PCM_RESOURCE_LIST ResourceList)
{
ok_eq_pointer(ResourceList, NULL);
}
/*
* Interface 1 Bus 0 Slot 0 AlternativeLists 2
*
* AltList 0, AltList->Count 2 Ver.1 Rev.30
* [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1
* [0:1:11] IO: Min 0:600, Max 0:607, Align 1 Len 1
*
* AltList 1, AltList->Count 2 Ver.1 Rev.31
* [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1
* [0:1:11] IO: Min 0:700, Max 0:708, Align 1 Len 1
*/
static
VOID
DrvTestCard1Dev2QueryResourceRequirements(
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
PIO_RESOURCE_DESCRIPTOR Descriptor;
PIO_RESOURCE_LIST AltList;
ok(ReqList != NULL, "ReqList is NULL\n");
if (ReqList == NULL)
{
skip("No ReqList\n");
return;
}
expect_requirements_list_header(ReqList, Isa, 2UL);
/************************* LIST 0 ************************/
AltList = &ReqList->List[0];
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 2UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x500ull,
0x506ull);
Descriptor++;
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x600ull,
0x607ull);
Descriptor++;
/************************* LIST 1 ************************/
AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count);
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 2UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x500ull,
0x506ull);
Descriptor++;
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x700ull,
0x708ull);
Descriptor++;
}
VOID
DrvTestCard1Dev2Resources(
_In_ PCM_RESOURCE_LIST ResourceList,
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
DrvTestCard1Dev2QueryResources(ResourceList);
DrvTestCard1Dev2QueryResourceRequirements(ReqList);
}
/* No boot resources */
static
VOID
DrvTestCard1Dev3QueryResources(
_In_ PCM_RESOURCE_LIST ResourceList)
{
ok_eq_pointer(ResourceList, NULL);
}
/*
* Interface 1 Bus 0 Slot 0 AlternativeLists 2
*
* AltList 0, AltList->Count 2 Ver.1 Rev.30
* [0:1:11] IO: Min 0:600, Max 0:607, Align 1 Len 1
* [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1
*
* AltList 1, AltList->Count 2 Ver.1 Rev.31
* [0:1:11] IO: Min 0:700, Max 0:708, Align 1 Len 1
* [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1
*/
static
VOID
DrvTestCard1Dev3QueryResourceRequirements(
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
PIO_RESOURCE_DESCRIPTOR Descriptor;
PIO_RESOURCE_LIST AltList;
ok(ReqList != NULL, "ReqList is NULL\n");
if (ReqList == NULL)
{
skip("No ReqList\n");
return;
}
expect_requirements_list_header(ReqList, Isa, 2UL);
/************************* LIST 0 ************************/
AltList = &ReqList->List[0];
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 2UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x600ull,
0x607ull);
Descriptor++;
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x500ull,
0x506ull);
Descriptor++;
/************************* LIST 1 ************************/
AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count);
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 2UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x700ull,
0x708ull);
Descriptor++;
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x500ull,
0x506ull);
Descriptor++;
}
VOID
DrvTestCard1Dev3Resources(
_In_ PCM_RESOURCE_LIST ResourceList,
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
DrvTestCard1Dev3QueryResources(ResourceList);
DrvTestCard1Dev3QueryResourceRequirements(ReqList);
}
/* No boot resources */
static
VOID
DrvTestCard1Dev4QueryResources(
_In_ PCM_RESOURCE_LIST ResourceList)
{
ok_eq_pointer(ResourceList, NULL);
}
/*
* Interface 1 Bus 0 Slot 0 AlternativeLists 2
*
* AltList 0, AltList->Count 1 Ver.1 Rev.30
* [0:1:11] IO: Min 0:600, Max 0:607, Align 1 Len 1
*
* AltList 1, AltList->Count 1 Ver.1 Rev.31
* [0:1:11] IO: Min 0:700, Max 0:708, Align 1 Len 1
*/
static
VOID
DrvTestCard1Dev4QueryResourceRequirements(
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
PIO_RESOURCE_DESCRIPTOR Descriptor;
PIO_RESOURCE_LIST AltList;
ok(ReqList != NULL, "ReqList is NULL\n");
if (ReqList == NULL)
{
skip("No ReqList\n");
return;
}
expect_requirements_list_header(ReqList, Isa, 2UL);
/************************* LIST 0 ************************/
AltList = &ReqList->List[0];
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 1UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x600ull,
0x607ull);
Descriptor++;
/************************* LIST 1 ************************/
AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count);
Descriptor = &AltList->Descriptors[0];
expect_alt_list_header(AltList, 1UL);
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE,
CmResourceShareDeviceExclusive,
1ul,
1ul,
0x700ull,
0x708ull);
Descriptor++;
}
VOID
DrvTestCard1Dev4Resources(
_In_ PCM_RESOURCE_LIST ResourceList,
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
DrvTestCard1Dev4QueryResources(ResourceList);
DrvTestCard1Dev4QueryResourceRequirements(ReqList);
}
/*
* FullList Count 1
* List #0 Iface 1 Bus #0 Ver.0 Rev.3000 Count 2
* [1:11] MEM: 0:D6000 Len 8000
* [1:11] MEM: 0:C8000 Len 8000
*/
static
VOID
DrvTestCard1Dev5QueryResources(
_In_ PCM_RESOURCE_LIST ResourceList)
{
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
ok(ResourceList != NULL, "ResourceList is NULL\n");
if (ResourceList == NULL)
{
skip("No ResourceList\n");
return;
}
expect_resource_list_header(ResourceList, Isa, 2UL);
Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
expect_mem_res(Descriptor,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x8000ul,
0xD6000ull);
Descriptor++;
expect_mem_res(Descriptor,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x8000ul,
0xC8000ull);
Descriptor++;
/*********************************************************/
ok_eq_size(GetPoolAllocSize(ResourceList), (ULONG_PTR)Descriptor - (ULONG_PTR)ResourceList);
}
/*
* Interface 1 Bus 0 Slot 0 AlternativeLists 1
*
* AltList 0, AltList->Count 3 Ver.1 Rev.30
* [1:3:0] CFG: Priority 2000 Res1 720075 Res2 650072
* [1:1:11] MEM: Min 0:D6000, Max 0:DDFFF, Align 1 Len 8000
* [1:1:11] MEM: Min 0:C8000, Max 0:CFFFF, Align 1 Len 8000
*
* OR (decodes disabled)
*
* AltList 0, AltList->Count 2 Ver.1 Rev.30
* [0:1:10] MEM: Min 0:D0000, Max 0:E7FFF, Align 100 Len 8000
* [0:1:10] MEM: Min 0:C8000, Max 0:CFFFF, Align 1 Len 8000
*/
static
VOID
DrvTestCard1Dev5QueryResourceRequirements(
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
PIO_RESOURCE_DESCRIPTOR Descriptor;
PIO_RESOURCE_LIST AltList;
ULONG Count;
ok(ReqList != NULL, "ReqList is NULL\n");
if (ReqList == NULL)
{
skip("No ReqList\n");
return;
}
expect_requirements_list_header(ReqList, Isa, 1UL);
/************************* LIST 0 ************************/
AltList = &ReqList->List[0];
Descriptor = &AltList->Descriptors[0];
if (Descriptor->Type == CmResourceTypeConfigData)
Count = 3;
else
Count = 2;
expect_alt_list_header(AltList, Count);
/* TODO: Should we support this? */
if (Descriptor->Type == CmResourceTypeConfigData)
{
expect_cfg_req(Descriptor,
IO_RESOURCE_PREFERRED,
0,
CmResourceShareShared,
0x2000ul,
0ul,
0ul);
Descriptor++;
}
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x8000ul,
0x100ul,
0xD0000ull,
0xE7FFFull);
Descriptor++;
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x8000ul,
0x1ul,
0xC8000ull,
0xCFFFFull);
Descriptor++;
/*********************************************************/
ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList));
ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList);
}
VOID
DrvTestCard1Dev5Resources(
_In_ PCM_RESOURCE_LIST ResourceList,
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
DrvTestCard1Dev5QueryResources(ResourceList);
DrvTestCard1Dev5QueryResourceRequirements(ReqList);
}
/*
* FullList Count 1
* List #0 Iface 1 Bus #0 Ver.0 Rev.3000 Count 4
* [1:11] MEM: 0:A0000 Len 4000
* [1:5] IO: Start 0:80, Len 8
* [1:0] DMA: Channel 6 Port 0 Res 0
* [1:1] INT: Lev 5 Vec 5 Aff FFFFFFFF
*/
static
VOID
DrvTestCard1Dev6QueryResources(
_In_ PCM_RESOURCE_LIST ResourceList)
{
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
ok(ResourceList != NULL, "ResourceList is NULL\n");
if (ResourceList == NULL)
{
skip("No ResourceList\n");
return;
}
expect_resource_list_header(ResourceList, Isa, 4UL);
Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
expect_port_res(Descriptor,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE,
CmResourceShareDeviceExclusive,
8ul,
0x80ull);
Descriptor++;
expect_irq_res(Descriptor,
CM_RESOURCE_INTERRUPT_LATCHED,
CmResourceShareDeviceExclusive,
5ul,
5ul,
(KAFFINITY)-1);
Descriptor++;
expect_dma_res(Descriptor,
0,
CmResourceShareDeviceExclusive,
6ul);
Descriptor++;
expect_mem_res(Descriptor,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x4000ul,
0xA0000ull);
Descriptor++;
/*********************************************************/
ok_eq_size(GetPoolAllocSize(ResourceList), (ULONG_PTR)Descriptor - (ULONG_PTR)ResourceList);
}
/*
* Interface 1 Bus 0 Slot 0 AlternativeLists 1
*
* AltList 0, AltList->Count 6 Ver.1 Rev.30
* [1:3:0] CFG: Priority 2000 Res1 7 Res2 0
* [1:1:11] MEM: Min 0:A0000, Max 0:A3FFF, Align 1 Len 4000
* [0:1:10] MEM: Min 0:80000, Max 0:900FF, Align 4 Len 100
* [1:0:0] DMA: Min 6 Max 6
* [1:1:1] INT: Min 5 Max 5
* [1:1:5] IO: Min 0:80, Max 0:87, Align 1 Len 8
*
* OR (decodes disabled)
*
* AltList 0, AltList->Count 5 Ver.1 Rev.30
* [0:1:10] MEM: Min 0:A0000, Max 0:A4FFF, Align 4 Len 1000
* [0:1:10] MEM: Min 0:80000, Max 0:900FF, Align 4 Len 100
* [0:0:0] DMA: Min 6 Max 6
* [0:1:1] INT: Min 5 Max 5
* [0:1:5] IO: Min 0:80, Max 0:87, Align 1 Len 8
*/
static
VOID
DrvTestCard1Dev6QueryResourceRequirements(
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
PIO_RESOURCE_DESCRIPTOR Descriptor;
PIO_RESOURCE_LIST AltList;
ULONG Count;
ok(ReqList != NULL, "ReqList is NULL\n");
if (ReqList == NULL)
{
skip("No ReqList\n");
return;
}
expect_requirements_list_header(ReqList, Isa, 1UL);
/************************* LIST 0 ************************/
AltList = &ReqList->List[0];
Descriptor = &AltList->Descriptors[0];
if (Descriptor->Type == CmResourceTypeConfigData)
Count = 6;
else
Count = 5;
expect_alt_list_header(AltList, Count);
/* TODO: Should we support this? */
if (Descriptor->Type == CmResourceTypeConfigData)
{
expect_cfg_req(Descriptor,
IO_RESOURCE_PREFERRED,
0,
CmResourceShareShared,
0x2000ul,
0ul,
0ul);
Descriptor++;
}
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x1000ul,
0x4ul,
0xA0000ull,
0xA4FFFull);
Descriptor++;
// NOTE: The native driver returns CM_RESOURCE_MEMORY_24 only for some reason
#if 0
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24,
CmResourceShareDeviceExclusive,
0x100ul,
0x4ul,
0x80000ull,
0x900FFull);
#else
expect_mem_req(Descriptor,
0,
CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY,
CmResourceShareDeviceExclusive,
0x100ul,
0x4ul,
0x80000ull,
0x900FFull);
#endif
Descriptor++;
expect_dma_req(Descriptor,
0,
CM_RESOURCE_DMA_8,
CmResourceShareUndetermined,
6ul,
6ul);
Descriptor++;
expect_irq_req(Descriptor,
0,
CM_RESOURCE_INTERRUPT_LATCHED,
CmResourceShareDeviceExclusive,
5ul,
5ul);
Descriptor++;
expect_port_req(Descriptor,
0,
CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE,
CmResourceShareDeviceExclusive,
8ul,
1ul,
0x80ull,
0x87ull);
Descriptor++;
/*********************************************************/
ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList));
ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList);
}
VOID
DrvTestCard1Dev6Resources(
_In_ PCM_RESOURCE_LIST ResourceList,
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
DrvTestCard1Dev6QueryResources(ResourceList);
DrvTestCard1Dev6QueryResourceRequirements(ReqList);
}
VOID
DrvTestCard1Dev6ConfigurationResult(
_In_ PISAPNP_CARD_LOGICAL_DEVICE LogDev)
{
ULONG i, Offset;
/* Memory Base #0 = 0xA2000 */
ok_eq_int(LogDev->Registers[0x40], 0x0A);
ok_eq_int(LogDev->Registers[0x41], 0x20);
/* Memory Control #0 = upper limit enabled, 16-bit memory */
ok_eq_int(LogDev->Registers[0x42], 0x03);
/* Memory Upper limit #0 = 0xA3000 (0xA2000 + 0x1000) */
ok_eq_int(LogDev->Registers[0x43], 0x0A);
ok_eq_int(LogDev->Registers[0x44], 0x30);
/* Memory Base #1 = 0x89000 */
ok_eq_int(LogDev->Registers[0x48], 0x08);
ok_eq_int(LogDev->Registers[0x49], 0x90);
/* Memory Control #1 = range length enabled, 8-bit memory */
ok_eq_int(LogDev->Registers[0x4A], 0x00);
/* Memory Upper limit #1 = 0xFFFF00 (0x100) */
ok_eq_int(LogDev->Registers[0x4B], 0xFF);
ok_eq_int(LogDev->Registers[0x4C], 0xFF);
/* Memory #2-3 should be disabled */
for (i = 2; i < 4; ++i)
{
Offset = 0x40 + i * 8;
/* Memory Base */
ok_eq_int(LogDev->Registers[Offset ], 0x00);
ok_eq_int(LogDev->Registers[Offset + 1], 0x00);
/* Memory Control */
ok_eq_int(LogDev->Registers[Offset + 2], 0x00);
/* Memory Upper limit or range length */
ok_eq_int(LogDev->Registers[Offset + 3], 0x00);
ok_eq_int(LogDev->Registers[Offset + 4], 0x00);
}
/* Memory 32 #0-3 should be disabled */
for (i = 0; i < 4; ++i)
{
if (i == 0)
Offset = 0x76;
else
Offset = 0x70 + i * 16;
/* Memory 32 Base */
ok_eq_int(LogDev->Registers[Offset ], 0x00);
ok_eq_int(LogDev->Registers[Offset + 1], 0x00);
ok_eq_int(LogDev->Registers[Offset + 2], 0x00);
ok_eq_int(LogDev->Registers[Offset + 3], 0x00);
/* Memory 32 Control */
ok_eq_int(LogDev->Registers[Offset + 4], 0x00);
/* Memory 32 Upper limit or range length */
ok_eq_int(LogDev->Registers[Offset + 5], 0x00);
ok_eq_int(LogDev->Registers[Offset + 6], 0x00);
ok_eq_int(LogDev->Registers[Offset + 7], 0x00);
ok_eq_int(LogDev->Registers[Offset + 8], 0x00);
}
/* I/O Base #0 = 0x80 */
ok_eq_int(LogDev->Registers[0x60], 0x00);
ok_eq_int(LogDev->Registers[0x61], 0x80);
/* I/O Base #1-6 should be disabled */
for (i = 1; i < 6; ++i)
{
Offset = 0x60 + i * 2;
ok_eq_int(LogDev->Registers[Offset ], 0x00);
ok_eq_int(LogDev->Registers[Offset + 1], 0x00);
}
/* IRQ select #0 = IRQ 5 low-to-high transition */
ok_eq_int(LogDev->Registers[0x70], 0x05);
ok_eq_int(LogDev->Registers[0x71], 0x02);
/* IRQ select #1 should be disabled */
ok_eq_int(LogDev->Registers[0x72], 0x00);
ok_eq_int(LogDev->Registers[0x73], 0x00);
/* DMA select #0 = DMA 6 */
ok_eq_int(LogDev->Registers[0x74], 0x06);
/* DMA select #1 = No DMA is active */
ok_eq_int(LogDev->Registers[0x75], 0x04);
}
PCM_RESOURCE_LIST
DrvTestCard1Dev6CreateConfigurationResources(VOID)
{
PCM_RESOURCE_LIST ResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
ULONG ListSize;
#define RESOURCE_COUNT 5
/*
* Make the following resources from the requirements:
*
* FullList Count 1
* List #0 Iface 1 Bus #0 Ver.1 Rev.1 Count 5
* [1:11] MEM: 0:A2000 Len 1000
* [1:11] MEM: 0:89000 Len 100
* [0:0] DMA: Channel 6 Port 0 Res 0
* [1:1] INT: Lev 5 Vec 3F Aff FFFFFFFF
* [1:5] IO: Start 0:80, Len 8
*/
ListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors) +
sizeof(*Descriptor) * RESOURCE_COUNT;
ResourceList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ListSize);
if (ResourceList == NULL)
return NULL;
ResourceList->Count = 1;
ResourceList->List[0].InterfaceType = Isa;
ResourceList->List[0].BusNumber = 0;
ResourceList->List[0].PartialResourceList.Version = 1;
ResourceList->List[0].PartialResourceList.Revision = 1;
ResourceList->List[0].PartialResourceList.Count = RESOURCE_COUNT;
Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY;
Descriptor->u.Memory.Start.LowPart = 0xA2000;
Descriptor->u.Memory.Length = 0x1000;
++Descriptor;
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY;
Descriptor->u.Memory.Start.LowPart = 0x89000;
Descriptor->u.Memory.Length = 0x100;
++Descriptor;
Descriptor->Type = CmResourceTypeDma;
Descriptor->ShareDisposition = CmResourceShareUndetermined;
Descriptor->Flags = CM_RESOURCE_DMA_8;
Descriptor->u.Dma.Channel = 6;
++Descriptor;
Descriptor->Type = CmResourceTypeInterrupt;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
Descriptor->u.Interrupt.Level = 5;
Descriptor->u.Interrupt.Vector = 0x3F;
Descriptor->u.Interrupt.Affinity = (KAFFINITY)-1;
++Descriptor;
Descriptor->Type = CmResourceTypePort;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE;
Descriptor->u.Memory.Start.LowPart = 0x80;
Descriptor->u.Memory.Length = 8;
return ResourceList;
}
VOID
DrvTestCard1Dev7Resources(
_In_ PCM_RESOURCE_LIST ResourceList,
_In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList)
{
/* No resources */
ok_eq_pointer(ResourceList, NULL);
ok_eq_pointer(ReqList, NULL);
}