Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/acpi/acpica/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  utaddress.c   Sprache: C

 
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/******************************************************************************
 *
 * Module Name: utaddress - op_region address range check
 *
 * Copyright (C) 2000 - 2025, Intel Corp.
 *
 *****************************************************************************/


#include <acpi/acpi.h>
#include "accommon.h"
#include "acnamesp.h"

#define _COMPONENT          ACPI_UTILITIES
ACPI_MODULE_NAME("utaddress")

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_add_address_range
 *
 * PARAMETERS:  space_id            - Address space ID
 *              address             - op_region start address
 *              length              - op_region length
 *              region_node         - op_region namespace node
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Add the Operation Region address range to the global list.
 *              The only supported Space IDs are Memory and I/O. Called when
 *              the op_region address/length operands are fully evaluated.
 *
 * MUTEX:       Locks the namespace
 *
 * NOTE: Because this interface is only called when an op_region argument
 * list is evaluated, there cannot be any duplicate region_nodes.
 * Duplicate Address/Length values are allowed, however, so that multiple
 * address conflicts can be detected.
 *
 ******************************************************************************/

acpi_status
acpi_ut_add_address_range(acpi_adr_space_type space_id,
     acpi_physical_address address,
     u32 length, struct acpi_namespace_node *region_node)
{
 struct acpi_address_range *range_info;

 ACPI_FUNCTION_TRACE(ut_add_address_range);

 if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
     (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
  return_ACPI_STATUS(AE_OK);
 }

 /* Allocate/init a new info block, add it to the appropriate list */

 range_info = ACPI_ALLOCATE(sizeof(struct acpi_address_range));
 if (!range_info) {
  return_ACPI_STATUS(AE_NO_MEMORY);
 }

 range_info->start_address = address;
 range_info->end_address = (address + length - 1);
 range_info->region_node = region_node;

 range_info->next = acpi_gbl_address_range_list[space_id];
 acpi_gbl_address_range_list[space_id] = range_info;

 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     "\nAdded [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n",
     acpi_ut_get_node_name(range_info->region_node),
     ACPI_FORMAT_UINT64(address),
     ACPI_FORMAT_UINT64(range_info->end_address)));

 return_ACPI_STATUS(AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_remove_address_range
 *
 * PARAMETERS:  space_id            - Address space ID
 *              region_node         - op_region namespace node
 *
 * RETURN:      None
 *
 * DESCRIPTION: Remove the Operation Region from the global list. The only
 *              supported Space IDs are Memory and I/O. Called when an
 *              op_region is deleted.
 *
 * MUTEX:       Assumes the namespace is locked
 *
 ******************************************************************************/


void
acpi_ut_remove_address_range(acpi_adr_space_type space_id,
        struct acpi_namespace_node *region_node)
{
 struct acpi_address_range *range_info;
 struct acpi_address_range *prev;

 ACPI_FUNCTION_TRACE(ut_remove_address_range);

 if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
     (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
  return_VOID;
 }

 /* Get the appropriate list head and check the list */

 range_info = prev = acpi_gbl_address_range_list[space_id];
 while (range_info) {
  if (range_info->region_node == region_node) {
   if (range_info == prev) { /* Found at list head */
    acpi_gbl_address_range_list[space_id] =
        range_info->next;
   } else {
    prev->next = range_info->next;
   }

   ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
       "\nRemoved [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n",
       acpi_ut_get_node_name(range_info->
        region_node),
       ACPI_FORMAT_UINT64(range_info->
            start_address),
       ACPI_FORMAT_UINT64(range_info->
            end_address)));

   ACPI_FREE(range_info);
   return_VOID;
  }

  prev = range_info;
  range_info = range_info->next;
 }

 return_VOID;
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_check_address_range
 *
 * PARAMETERS:  space_id            - Address space ID
 *              address             - Start address
 *              length              - Length of address range
 *              warn                - TRUE if warning on overlap desired
 *
 * RETURN:      Count of the number of conflicts detected. Zero is always
 *              returned for Space IDs other than Memory or I/O.
 *
 * DESCRIPTION: Check if the input address range overlaps any of the
 *              ASL operation region address ranges. The only supported
 *              Space IDs are Memory and I/O.
 *
 * MUTEX:       Assumes the namespace is locked.
 *
 ******************************************************************************/


u32
acpi_ut_check_address_range(acpi_adr_space_type space_id,
       acpi_physical_address address, u32 length, u8 warn)
{
 struct acpi_address_range *range_info;
 acpi_physical_address end_address;
 char *pathname;
 u32 overlap_count = 0;

 ACPI_FUNCTION_TRACE(ut_check_address_range);

 if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
     (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
  return_UINT32(0);
 }

 range_info = acpi_gbl_address_range_list[space_id];
 end_address = address + length - 1;

 /* Check entire list for all possible conflicts */

 while (range_info) {
  /*
 * Check if the requested address/length overlaps this
 * address range. There are four cases to consider:
 *
 * 1) Input address/length is contained completely in the
 *    address range
 * 2) Input address/length overlaps range at the range start
 * 3) Input address/length overlaps range at the range end
 * 4) Input address/length completely encompasses the range
 */

  if ((address <= range_info->end_address) &&
      (end_address >= range_info->start_address)) {

   /* Found an address range overlap */

   overlap_count++;
   if (warn) { /* Optional warning message */
    pathname =
        acpi_ns_get_normalized_pathname(range_info->
            region_node,
            TRUE);

    ACPI_WARNING((AE_INFO,
           "%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)",
           acpi_ut_get_region_name(space_id),
           ACPI_FORMAT_UINT64(address),
           ACPI_FORMAT_UINT64(end_address),
           ACPI_FORMAT_UINT64(range_info->
         start_address),
           ACPI_FORMAT_UINT64(range_info->
         end_address),
           pathname));
    ACPI_FREE(pathname);
   }
  }

  range_info = range_info->next;
 }

 return_UINT32(overlap_count);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_delete_address_lists
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Delete all global address range lists (called during
 *              subsystem shutdown).
 *
 ******************************************************************************/


void acpi_ut_delete_address_lists(void)
{
 struct acpi_address_range *next;
 struct acpi_address_range *range_info;
 int i;

 /* Delete all elements in all address range lists */

 for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
  next = acpi_gbl_address_range_list[i];

  while (next) {
   range_info = next;
   next = range_info->next;
   ACPI_FREE(range_info);
  }

  acpi_gbl_address_range_list[i] = NULL;
 }
}

Messung V0.5
C=89 H=91 G=89

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.