Module Name: src Committed By: riastradh Date: Fri Mar 22 20:47:52 UTC 2024
Modified Files: src/sys/dev/acpi: apei_mapreg.c Log Message: apei(4): Allow pre-mapping I/O registers too. PR kern/58046 To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/acpi/apei_mapreg.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/acpi/apei_mapreg.c diff -u src/sys/dev/acpi/apei_mapreg.c:1.3 src/sys/dev/acpi/apei_mapreg.c:1.4 --- src/sys/dev/acpi/apei_mapreg.c:1.3 Fri Mar 22 20:47:31 2024 +++ src/sys/dev/acpi/apei_mapreg.c Fri Mar 22 20:47:52 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: apei_mapreg.c,v 1.3 2024/03/22 20:47:31 riastradh Exp $ */ +/* $NetBSD: apei_mapreg.c,v 1.4 2024/03/22 20:47:52 riastradh Exp $ */ /*- * Copyright (c) 2024 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: apei_mapreg.c,v 1.3 2024/03/22 20:47:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: apei_mapreg.c,v 1.4 2024/03/22 20:47:52 riastradh Exp $"); #include <sys/types.h> @@ -73,7 +73,10 @@ apei_mapreg_map(const ACPI_GENERIC_ADDRE case 1: /* 8-bit */ case 2: /* 16-bit */ case 3: /* 32-bit */ + break; case 4: /* 64-bit */ + if (reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO) + return NULL; break; default: return NULL; @@ -100,11 +103,14 @@ apei_mapreg_map(const ACPI_GENERIC_ADDRE /* * Dispatch on the space id. - * - * Currently this only handles memory space because I/O space - * is too painful to contemplate reimplementing here. */ switch (reg->SpaceId) { + case ACPI_ADR_SPACE_SYSTEM_IO: + /* + * Just need to return something non-null -- no state + * to record for a mapping. + */ + return (struct apei_mapreg *)__UNCONST(reg); case ACPI_ADR_SPACE_SYSTEM_MEMORY: return AcpiOsMapMemory(reg->Address, 1 << (reg->AccessWidth - 1)); @@ -123,7 +129,16 @@ apei_mapreg_unmap(const ACPI_GENERIC_ADD struct apei_mapreg *map) { - AcpiOsUnmapMemory(map, 1 << (reg->AccessWidth - 1)); + switch (reg->SpaceId) { + case ACPI_ADR_SPACE_SYSTEM_IO: + KASSERT(map == __UNCONST(reg)); + break; + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + AcpiOsUnmapMemory(map, 1 << (reg->AccessWidth - 1)); + break; + default: + panic("invalid register mapping"); + } } /* @@ -142,18 +157,50 @@ apei_mapreg_read(const ACPI_GENERIC_ADDR for (i = 0; i < n; i++) { uint64_t chunk; - switch (reg->AccessWidth) { - case 1: - chunk = *((volatile const uint8_t *)map + i); + switch (reg->SpaceId) { + case ACPI_ADR_SPACE_SYSTEM_IO: { + ACPI_IO_ADDRESS addr; + uint32_t chunk32 = 0; + ACPI_STATUS rv; + + switch (reg->AccessWidth) { + case 1: + addr = reg->Address + i; + break; + case 2: + addr = reg->Address + 2*i; + break; + case 3: + addr = reg->Address + 4*i; + break; + case 4: /* no 64-bit I/O ports */ + default: + __unreachable(); + } + rv = AcpiOsReadPort(addr, &chunk32, + NBBY*(1 << (reg->AccessWidth - 1))); + KASSERTMSG(!ACPI_FAILURE(rv), "%s", + AcpiFormatException(rv)); + chunk = chunk32; break; - case 2: - chunk = *((volatile const uint16_t *)map + i); - break; - case 3: - chunk = *((volatile const uint32_t *)map + i); - break; - case 4: - chunk = *((volatile const uint64_t *)map + i); + } + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + switch (reg->AccessWidth) { + case 1: + chunk = *((volatile const uint8_t *)map + i); + break; + case 2: + chunk = *((volatile const uint16_t *)map + i); + break; + case 3: + chunk = *((volatile const uint32_t *)map + i); + break; + case 4: + chunk = *((volatile const uint64_t *)map + i); + break; + default: + __unreachable(); + } break; default: __unreachable(); @@ -181,18 +228,48 @@ apei_mapreg_write(const ACPI_GENERIC_ADD for (i = 0; i < n; i++) { uint64_t chunk = v >> (i*chunkbits); - switch (reg->AccessWidth) { - case 1: - *((volatile uint8_t *)map + i) = chunk; + switch (reg->SpaceId) { + case ACPI_ADR_SPACE_SYSTEM_IO: { + ACPI_IO_ADDRESS addr; + ACPI_STATUS rv; + + switch (reg->AccessWidth) { + case 1: + addr = reg->Address + i; + break; + case 2: + addr = reg->Address + 2*i; + break; + case 3: + addr = reg->Address + 4*i; + break; + case 4: /* no 64-bit I/O ports */ + default: + __unreachable(); + } + rv = AcpiOsWritePort(addr, chunk, + NBBY*(1 << (reg->AccessWidth - 1))); + KASSERTMSG(!ACPI_FAILURE(rv), "%s", + AcpiFormatException(rv)); break; - case 2: - *((volatile uint16_t *)map + i) = chunk; - break; - case 3: - *((volatile uint32_t *)map + i) = chunk; - break; - case 4: - *((volatile uint64_t *)map + i) = chunk; + } + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + switch (reg->AccessWidth) { + case 1: + *((volatile uint8_t *)map + i) = chunk; + break; + case 2: + *((volatile uint16_t *)map + i) = chunk; + break; + case 3: + *((volatile uint32_t *)map + i) = chunk; + break; + case 4: + *((volatile uint64_t *)map + i) = chunk; + break; + default: + __unreachable(); + } break; default: __unreachable();