0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013
0014 #define _COMPONENT ACPI_UTILITIES
0015 ACPI_MODULE_NAME("utaddress")
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 acpi_status
0041 acpi_ut_add_address_range(acpi_adr_space_type space_id,
0042 acpi_physical_address address,
0043 u32 length, struct acpi_namespace_node *region_node)
0044 {
0045 struct acpi_address_range *range_info;
0046
0047 ACPI_FUNCTION_TRACE(ut_add_address_range);
0048
0049 if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
0050 (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
0051 return_ACPI_STATUS(AE_OK);
0052 }
0053
0054
0055
0056 range_info = ACPI_ALLOCATE(sizeof(struct acpi_address_range));
0057 if (!range_info) {
0058 return_ACPI_STATUS(AE_NO_MEMORY);
0059 }
0060
0061 range_info->start_address = address;
0062 range_info->end_address = (address + length - 1);
0063 range_info->region_node = region_node;
0064
0065 range_info->next = acpi_gbl_address_range_list[space_id];
0066 acpi_gbl_address_range_list[space_id] = range_info;
0067
0068 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0069 "\nAdded [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n",
0070 acpi_ut_get_node_name(range_info->region_node),
0071 ACPI_FORMAT_UINT64(address),
0072 ACPI_FORMAT_UINT64(range_info->end_address)));
0073
0074 return_ACPI_STATUS(AE_OK);
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 void
0095 acpi_ut_remove_address_range(acpi_adr_space_type space_id,
0096 struct acpi_namespace_node *region_node)
0097 {
0098 struct acpi_address_range *range_info;
0099 struct acpi_address_range *prev;
0100
0101 ACPI_FUNCTION_TRACE(ut_remove_address_range);
0102
0103 if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
0104 (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
0105 return_VOID;
0106 }
0107
0108
0109
0110 range_info = prev = acpi_gbl_address_range_list[space_id];
0111 while (range_info) {
0112 if (range_info->region_node == region_node) {
0113 if (range_info == prev) {
0114 acpi_gbl_address_range_list[space_id] =
0115 range_info->next;
0116 } else {
0117 prev->next = range_info->next;
0118 }
0119
0120 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0121 "\nRemoved [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n",
0122 acpi_ut_get_node_name(range_info->
0123 region_node),
0124 ACPI_FORMAT_UINT64(range_info->
0125 start_address),
0126 ACPI_FORMAT_UINT64(range_info->
0127 end_address)));
0128
0129 ACPI_FREE(range_info);
0130 return_VOID;
0131 }
0132
0133 prev = range_info;
0134 range_info = range_info->next;
0135 }
0136
0137 return_VOID;
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 u32
0161 acpi_ut_check_address_range(acpi_adr_space_type space_id,
0162 acpi_physical_address address, u32 length, u8 warn)
0163 {
0164 struct acpi_address_range *range_info;
0165 acpi_physical_address end_address;
0166 char *pathname;
0167 u32 overlap_count = 0;
0168
0169 ACPI_FUNCTION_TRACE(ut_check_address_range);
0170
0171 if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
0172 (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
0173 return_UINT32(0);
0174 }
0175
0176 range_info = acpi_gbl_address_range_list[space_id];
0177 end_address = address + length - 1;
0178
0179
0180
0181 while (range_info) {
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 if ((address <= range_info->end_address) &&
0193 (end_address >= range_info->start_address)) {
0194
0195
0196
0197 overlap_count++;
0198 if (warn) {
0199 pathname =
0200 acpi_ns_get_normalized_pathname(range_info->
0201 region_node,
0202 TRUE);
0203
0204 ACPI_WARNING((AE_INFO,
0205 "%s range 0x%8.8X%8.8X-0x%8.8X%8.8X conflicts with OpRegion 0x%8.8X%8.8X-0x%8.8X%8.8X (%s)",
0206 acpi_ut_get_region_name(space_id),
0207 ACPI_FORMAT_UINT64(address),
0208 ACPI_FORMAT_UINT64(end_address),
0209 ACPI_FORMAT_UINT64(range_info->
0210 start_address),
0211 ACPI_FORMAT_UINT64(range_info->
0212 end_address),
0213 pathname));
0214 ACPI_FREE(pathname);
0215 }
0216 }
0217
0218 range_info = range_info->next;
0219 }
0220
0221 return_UINT32(overlap_count);
0222 }
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237 void acpi_ut_delete_address_lists(void)
0238 {
0239 struct acpi_address_range *next;
0240 struct acpi_address_range *range_info;
0241 int i;
0242
0243
0244
0245 for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
0246 next = acpi_gbl_address_range_list[i];
0247
0248 while (next) {
0249 range_info = next;
0250 next = range_info->next;
0251 ACPI_FREE(range_info);
0252 }
0253
0254 acpi_gbl_address_range_list[i] = NULL;
0255 }
0256 }