xref: /linux/drivers/acpi/acpica/rsaddr.c (revision c13aca79ff3c4af5fd31a5b2743a90eba6e36a26)
1*95857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
21da177e4SLinus Torvalds /*******************************************************************************
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Module Name: rsaddr - Address resource descriptors (16/32/64)
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  ******************************************************************************/
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #include <acpi/acpi.h>
9e2f7a777SLen Brown #include "accommon.h"
10e2f7a777SLen Brown #include "acresrc.h"
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #define _COMPONENT          ACPI_RESOURCES
131da177e4SLinus Torvalds ACPI_MODULE_NAME("rsaddr")
141da177e4SLinus Torvalds 
150897831bSBob Moore /*******************************************************************************
160897831bSBob Moore  *
170897831bSBob Moore  * acpi_rs_convert_address16 - All WORD (16-bit) address resources
180897831bSBob Moore  *
190897831bSBob Moore  ******************************************************************************/
200897831bSBob Moore struct acpi_rsconvert_info acpi_rs_convert_address16[5] = {
210897831bSBob Moore 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,
220897831bSBob Moore 	 ACPI_RS_SIZE(struct acpi_resource_address16),
230897831bSBob Moore 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)},
24aff8c277SRobert Moore 
250897831bSBob Moore 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,
260897831bSBob Moore 	 sizeof(struct aml_resource_address16),
270897831bSBob Moore 	 0},
28aff8c277SRobert Moore 
290897831bSBob Moore 	/* Resource Type, General Flags, and Type-Specific Flags */
30aff8c277SRobert Moore 
310897831bSBob Moore 	{ACPI_RSC_ADDRESS, 0, 0, 0},
32aff8c277SRobert Moore 
330897831bSBob Moore 	/*
340897831bSBob Moore 	 * These fields are contiguous in both the source and destination:
350897831bSBob Moore 	 * Address Granularity
360897831bSBob Moore 	 * Address Range Minimum
370897831bSBob Moore 	 * Address Range Maximum
380897831bSBob Moore 	 * Address Translation Offset
390897831bSBob Moore 	 * Address Length
400897831bSBob Moore 	 */
41a45de93eSLv Zheng 	{ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.address.granularity),
420897831bSBob Moore 	 AML_OFFSET(address16.granularity),
430897831bSBob Moore 	 5},
4450eca3ebSBob Moore 
450897831bSBob Moore 	/* Optional resource_source (Index and String) */
460897831bSBob Moore 
470897831bSBob Moore 	{ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source),
480897831bSBob Moore 	 0,
490897831bSBob Moore 	 sizeof(struct aml_resource_address16)}
500897831bSBob Moore };
510897831bSBob Moore 
520897831bSBob Moore /*******************************************************************************
530897831bSBob Moore  *
540897831bSBob Moore  * acpi_rs_convert_address32 - All DWORD (32-bit) address resources
550897831bSBob Moore  *
560897831bSBob Moore  ******************************************************************************/
570897831bSBob Moore 
580897831bSBob Moore struct acpi_rsconvert_info acpi_rs_convert_address32[5] = {
590897831bSBob Moore 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,
600897831bSBob Moore 	 ACPI_RS_SIZE(struct acpi_resource_address32),
610897831bSBob Moore 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)},
620897831bSBob Moore 
630897831bSBob Moore 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,
640897831bSBob Moore 	 sizeof(struct aml_resource_address32),
650897831bSBob Moore 	 0},
660897831bSBob Moore 
670897831bSBob Moore 	/* Resource Type, General Flags, and Type-Specific Flags */
680897831bSBob Moore 
690897831bSBob Moore 	{ACPI_RSC_ADDRESS, 0, 0, 0},
700897831bSBob Moore 
710897831bSBob Moore 	/*
720897831bSBob Moore 	 * These fields are contiguous in both the source and destination:
730897831bSBob Moore 	 * Address Granularity
740897831bSBob Moore 	 * Address Range Minimum
750897831bSBob Moore 	 * Address Range Maximum
760897831bSBob Moore 	 * Address Translation Offset
770897831bSBob Moore 	 * Address Length
780897831bSBob Moore 	 */
79a45de93eSLv Zheng 	{ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.address.granularity),
800897831bSBob Moore 	 AML_OFFSET(address32.granularity),
810897831bSBob Moore 	 5},
820897831bSBob Moore 
830897831bSBob Moore 	/* Optional resource_source (Index and String) */
840897831bSBob Moore 
850897831bSBob Moore 	{ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source),
860897831bSBob Moore 	 0,
870897831bSBob Moore 	 sizeof(struct aml_resource_address32)}
880897831bSBob Moore };
890897831bSBob Moore 
900897831bSBob Moore /*******************************************************************************
910897831bSBob Moore  *
920897831bSBob Moore  * acpi_rs_convert_address64 - All QWORD (64-bit) address resources
930897831bSBob Moore  *
940897831bSBob Moore  ******************************************************************************/
950897831bSBob Moore 
960897831bSBob Moore struct acpi_rsconvert_info acpi_rs_convert_address64[5] = {
970897831bSBob Moore 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,
980897831bSBob Moore 	 ACPI_RS_SIZE(struct acpi_resource_address64),
990897831bSBob Moore 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)},
1000897831bSBob Moore 
1010897831bSBob Moore 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,
1020897831bSBob Moore 	 sizeof(struct aml_resource_address64),
1030897831bSBob Moore 	 0},
1040897831bSBob Moore 
1050897831bSBob Moore 	/* Resource Type, General Flags, and Type-Specific Flags */
1060897831bSBob Moore 
1070897831bSBob Moore 	{ACPI_RSC_ADDRESS, 0, 0, 0},
1080897831bSBob Moore 
1090897831bSBob Moore 	/*
1100897831bSBob Moore 	 * These fields are contiguous in both the source and destination:
1110897831bSBob Moore 	 * Address Granularity
1120897831bSBob Moore 	 * Address Range Minimum
1130897831bSBob Moore 	 * Address Range Maximum
1140897831bSBob Moore 	 * Address Translation Offset
1150897831bSBob Moore 	 * Address Length
1160897831bSBob Moore 	 */
117a45de93eSLv Zheng 	{ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.address.granularity),
1180897831bSBob Moore 	 AML_OFFSET(address64.granularity),
1190897831bSBob Moore 	 5},
1200897831bSBob Moore 
1210897831bSBob Moore 	/* Optional resource_source (Index and String) */
1220897831bSBob Moore 
1230897831bSBob Moore 	{ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source),
1240897831bSBob Moore 	 0,
1250897831bSBob Moore 	 sizeof(struct aml_resource_address64)}
1260897831bSBob Moore };
1270897831bSBob Moore 
1280897831bSBob Moore /*******************************************************************************
1290897831bSBob Moore  *
1300897831bSBob Moore  * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources
1310897831bSBob Moore  *
1320897831bSBob Moore  ******************************************************************************/
1330897831bSBob Moore 
1340897831bSBob Moore struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = {
1350897831bSBob Moore 	{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
1360897831bSBob Moore 	 ACPI_RS_SIZE(struct acpi_resource_extended_address64),
1370897831bSBob Moore 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)},
1380897831bSBob Moore 
1390897831bSBob Moore 	{ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
1400897831bSBob Moore 	 sizeof(struct aml_resource_extended_address64),
1410897831bSBob Moore 	 0},
1420897831bSBob Moore 
1430897831bSBob Moore 	/* Resource Type, General Flags, and Type-Specific Flags */
1440897831bSBob Moore 
1450897831bSBob Moore 	{ACPI_RSC_ADDRESS, 0, 0, 0},
1460897831bSBob Moore 
1470897831bSBob Moore 	/* Revision ID */
1480897831bSBob Moore 
149ba494beeSBob Moore 	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_ID),
150ba494beeSBob Moore 	 AML_OFFSET(ext_address64.revision_ID),
1510897831bSBob Moore 	 1},
1520897831bSBob Moore 	/*
1530897831bSBob Moore 	 * These fields are contiguous in both the source and destination:
1540897831bSBob Moore 	 * Address Granularity
1550897831bSBob Moore 	 * Address Range Minimum
1560897831bSBob Moore 	 * Address Range Maximum
1570897831bSBob Moore 	 * Address Translation Offset
1580897831bSBob Moore 	 * Address Length
1590897831bSBob Moore 	 * Type-Specific Attribute
1600897831bSBob Moore 	 */
161a45de93eSLv Zheng 	{ACPI_RSC_MOVE64,
162a45de93eSLv Zheng 	 ACPI_RS_OFFSET(data.ext_address64.address.granularity),
1630897831bSBob Moore 	 AML_OFFSET(ext_address64.granularity),
1640897831bSBob Moore 	 6}
1650897831bSBob Moore };
1660897831bSBob Moore 
1670897831bSBob Moore /*******************************************************************************
1680897831bSBob Moore  *
1690897831bSBob Moore  * acpi_rs_convert_general_flags - Flags common to all address descriptors
1700897831bSBob Moore  *
1710897831bSBob Moore  ******************************************************************************/
1720897831bSBob Moore 
1730897831bSBob Moore static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = {
1740897831bSBob Moore 	{ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags),
1750897831bSBob Moore 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)},
1760897831bSBob Moore 
1770897831bSBob Moore 	/* Resource Type (Memory, Io, bus_number, etc.) */
1780897831bSBob Moore 
1790897831bSBob Moore 	{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type),
1800897831bSBob Moore 	 AML_OFFSET(address.resource_type),
1810897831bSBob Moore 	 1},
1820897831bSBob Moore 
183ba494beeSBob Moore 	/* General flags - Consume, Decode, min_fixed, max_fixed */
1840897831bSBob Moore 
1850897831bSBob Moore 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer),
1860897831bSBob Moore 	 AML_OFFSET(address.flags),
1870897831bSBob Moore 	 0},
1880897831bSBob Moore 
1890897831bSBob Moore 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode),
1900897831bSBob Moore 	 AML_OFFSET(address.flags),
1910897831bSBob Moore 	 1},
1920897831bSBob Moore 
1930897831bSBob Moore 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed),
1940897831bSBob Moore 	 AML_OFFSET(address.flags),
1950897831bSBob Moore 	 2},
1960897831bSBob Moore 
1970897831bSBob Moore 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed),
1980897831bSBob Moore 	 AML_OFFSET(address.flags),
1990897831bSBob Moore 	 3}
2000897831bSBob Moore };
2010897831bSBob Moore 
2020897831bSBob Moore /*******************************************************************************
2030897831bSBob Moore  *
2040897831bSBob Moore  * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors
2050897831bSBob Moore  *
2060897831bSBob Moore  ******************************************************************************/
2070897831bSBob Moore 
2080897831bSBob Moore static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = {
2090897831bSBob Moore 	{ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
2100897831bSBob Moore 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)},
2110897831bSBob Moore 
2120897831bSBob Moore 	/* Memory-specific flags */
2130897831bSBob Moore 
2140897831bSBob Moore 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect),
2150897831bSBob Moore 	 AML_OFFSET(address.specific_flags),
2160897831bSBob Moore 	 0},
2170897831bSBob Moore 
2180897831bSBob Moore 	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching),
2190897831bSBob Moore 	 AML_OFFSET(address.specific_flags),
2200897831bSBob Moore 	 1},
2210897831bSBob Moore 
2220897831bSBob Moore 	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type),
2230897831bSBob Moore 	 AML_OFFSET(address.specific_flags),
2240897831bSBob Moore 	 3},
2250897831bSBob Moore 
2260897831bSBob Moore 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation),
2270897831bSBob Moore 	 AML_OFFSET(address.specific_flags),
2280897831bSBob Moore 	 5}
2290897831bSBob Moore };
2300897831bSBob Moore 
2310897831bSBob Moore /*******************************************************************************
2320897831bSBob Moore  *
2330897831bSBob Moore  * acpi_rs_convert_io_flags - Flags common to I/O address descriptors
2340897831bSBob Moore  *
2350897831bSBob Moore  ******************************************************************************/
2360897831bSBob Moore 
2370897831bSBob Moore static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = {
2380897831bSBob Moore 	{ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
2390897831bSBob Moore 	 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)},
2400897831bSBob Moore 
2410897831bSBob Moore 	/* I/O-specific flags */
2420897831bSBob Moore 
2430897831bSBob Moore 	{ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type),
2440897831bSBob Moore 	 AML_OFFSET(address.specific_flags),
2450897831bSBob Moore 	 0},
2460897831bSBob Moore 
2470897831bSBob Moore 	{ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation),
2480897831bSBob Moore 	 AML_OFFSET(address.specific_flags),
2490897831bSBob Moore 	 4},
2500897831bSBob Moore 
2510897831bSBob Moore 	{ACPI_RSC_1BITFLAG,
2520897831bSBob Moore 	 ACPI_RS_OFFSET(data.address.info.io.translation_type),
2530897831bSBob Moore 	 AML_OFFSET(address.specific_flags),
2540897831bSBob Moore 	 5}
2550897831bSBob Moore };
2560897831bSBob Moore 
2570897831bSBob Moore /*******************************************************************************
2580897831bSBob Moore  *
2590897831bSBob Moore  * FUNCTION:    acpi_rs_get_address_common
2600897831bSBob Moore  *
261ba494beeSBob Moore  * PARAMETERS:  resource            - Pointer to the internal resource struct
262ba494beeSBob Moore  *              aml                 - Pointer to the AML resource descriptor
2630897831bSBob Moore  *
2640897831bSBob Moore  * RETURN:      TRUE if the resource_type field is OK, FALSE otherwise
2650897831bSBob Moore  *
2660897831bSBob Moore  * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
2670897831bSBob Moore  *              to an internal resource descriptor
2680897831bSBob Moore  *
2690897831bSBob Moore  ******************************************************************************/
2700897831bSBob Moore 
2710897831bSBob Moore u8
27250eca3ebSBob Moore acpi_rs_get_address_common(struct acpi_resource *resource,
2730897831bSBob Moore 			   union aml_resource *aml)
274aff8c277SRobert Moore {
275aff8c277SRobert Moore 	ACPI_FUNCTION_ENTRY();
276aff8c277SRobert Moore 
2770897831bSBob Moore 	/* Validate the Resource Type */
278aff8c277SRobert Moore 
2791fad8738SBob Moore 	if ((aml->address.resource_type > 2) &&
2801fad8738SBob Moore 	    (aml->address.resource_type < 0xC0)) {
2810897831bSBob Moore 		return (FALSE);
282aff8c277SRobert Moore 	}
283aff8c277SRobert Moore 
2840897831bSBob Moore 	/* Get the Resource Type and General Flags */
285aff8c277SRobert Moore 
2860897831bSBob Moore 	(void)acpi_rs_convert_aml_to_resource(resource, aml,
2870897831bSBob Moore 					      acpi_rs_convert_general_flags);
288aff8c277SRobert Moore 
2890897831bSBob Moore 	/* Get the Type-Specific Flags (Memory and I/O descriptors only) */
29050eca3ebSBob Moore 
2910897831bSBob Moore 	if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
2920897831bSBob Moore 		(void)acpi_rs_convert_aml_to_resource(resource, aml,
2930897831bSBob Moore 						      acpi_rs_convert_mem_flags);
2940897831bSBob Moore 	} else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
2950897831bSBob Moore 		(void)acpi_rs_convert_aml_to_resource(resource, aml,
2960897831bSBob Moore 						      acpi_rs_convert_io_flags);
2970897831bSBob Moore 	} else {
2980897831bSBob Moore 		/* Generic resource type, just grab the type_specific byte */
2990897831bSBob Moore 
3000897831bSBob Moore 		resource->data.address.info.type_specific =
3010897831bSBob Moore 		    aml->address.specific_flags;
302aff8c277SRobert Moore 	}
303aff8c277SRobert Moore 
3040897831bSBob Moore 	return (TRUE);
305aff8c277SRobert Moore }
306aff8c277SRobert Moore 
3071da177e4SLinus Torvalds /*******************************************************************************
3081da177e4SLinus Torvalds  *
30950eca3ebSBob Moore  * FUNCTION:    acpi_rs_set_address_common
3101da177e4SLinus Torvalds  *
311ba494beeSBob Moore  * PARAMETERS:  aml                 - Pointer to the AML resource descriptor
312ba494beeSBob Moore  *              resource            - Pointer to the internal resource struct
3131da177e4SLinus Torvalds  *
31450eca3ebSBob Moore  * RETURN:      None
3151da177e4SLinus Torvalds  *
31650eca3ebSBob Moore  * DESCRIPTION: Convert common flag fields from a resource descriptor to an
31750eca3ebSBob Moore  *              AML descriptor
3181da177e4SLinus Torvalds  *
3191da177e4SLinus Torvalds  ******************************************************************************/
320aff8c277SRobert Moore 
3210897831bSBob Moore void
32250eca3ebSBob Moore acpi_rs_set_address_common(union aml_resource *aml,
32350eca3ebSBob Moore 			   struct acpi_resource *resource)
3241da177e4SLinus Torvalds {
32550eca3ebSBob Moore 	ACPI_FUNCTION_ENTRY();
3261da177e4SLinus Torvalds 
3270897831bSBob Moore 	/* Set the Resource Type and General Flags */
3281da177e4SLinus Torvalds 
3290897831bSBob Moore 	(void)acpi_rs_convert_resource_to_aml(resource, aml,
3300897831bSBob Moore 					      acpi_rs_convert_general_flags);
3311da177e4SLinus Torvalds 
3320897831bSBob Moore 	/* Set the Type-Specific Flags (Memory and I/O descriptors only) */
33344f6c012SRobert Moore 
3340897831bSBob Moore 	if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
3350897831bSBob Moore 		(void)acpi_rs_convert_resource_to_aml(resource, aml,
3360897831bSBob Moore 						      acpi_rs_convert_mem_flags);
3370897831bSBob Moore 	} else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
3380897831bSBob Moore 		(void)acpi_rs_convert_resource_to_aml(resource, aml,
3390897831bSBob Moore 						      acpi_rs_convert_io_flags);
3400897831bSBob Moore 	} else {
3410897831bSBob Moore 		/* Generic resource type, just copy the type_specific byte */
34244f6c012SRobert Moore 
34350eca3ebSBob Moore 		aml->address.specific_flags =
3440897831bSBob Moore 		    resource->data.address.info.type_specific;
34550eca3ebSBob Moore 	}
3461da177e4SLinus Torvalds }
347