From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E81EECDD540 for ; Wed, 18 Sep 2024 15:22:16 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3184188D92; Wed, 18 Sep 2024 17:22:03 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=9elements.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; secure) header.d=9elements.com header.i=@9elements.com header.b="RxnGtB/H"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 85CF488D59; Wed, 18 Sep 2024 17:22:02 +0200 (CEST) Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4BDB288D6B for ; Wed, 18 Sep 2024 17:22:00 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=9elements.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=patrick.rudolph@9elements.com Received: by mail-ej1-x633.google.com with SMTP id a640c23a62f3a-a8b155b5e9eso973324766b.1 for ; Wed, 18 Sep 2024 08:22:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=9elements.com; s=google; t=1726672920; x=1727277720; darn=lists.denx.de; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CGJqfuhZBEu98CnER+e3Zbgecg1wmcrTTHSvulklI6U=; b=RxnGtB/HC4VnvaWng/yZuYr/X9b/jbZS2E/TuMBQ2ohuo7QaHLVTiMQcRxYU7FvTCO ma1AcaYZL3YYfqIaUqtPnLnpJnwE8mj5TTMrjdnUGM+1nAMMTOl2hTLm/cZ1TD9OTMb/ bkarLdksJO6Y7To05Lg+3lOgQGCsH8jmkQ2TogR0gCzdXTe05Jy2yGB0TfRDeGQw7CVe ZDZjEcye81tQ9geSn9i3n6A3qcSKuhUcGZj82jbayoTDD2EOh6+FZu5D9MPGmkNCBZ7x 6VjSjGvJpOHDmvwAuqLAr/d9XbVqX4sy671XvFqhf0FBOTlvfxVVdn5tuXXXrHB97FJr roMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726672920; x=1727277720; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CGJqfuhZBEu98CnER+e3Zbgecg1wmcrTTHSvulklI6U=; b=Bo1elE+YdtWthqkqySO1nz1khHb/y6F9daB9gQe76DOjOzFvZzwLytyVBe+WdqpVhw 8l3JOGWP360We+kQbbLmUOzMcxFH/arD3O+2VwyZG3Tv3x6kA+Yi2jIZ8F/H3Yel76GB XOgU6XlguPLMNHxnjA9XW6OtdyxJgtGsUUT6gAxTSe8Y1lKQ2aBGcOG4piF1zhy0Mwbg w8t6SLLzzcTsbvFYep2fEH2EAQZGlb9T7k3oWuDowvrMWF/MGj3gKBcFkFZyUFDmvI9j x9CBfdyqPVdE+KbCG1hUseSxwpi9RtdGil3g7ksEmLvn4Z0X7mVf9oEbVpYUF3v/ZrQu B/1A== X-Gm-Message-State: AOJu0YxgkOLmtqBDB3ZcTk+WbZjs4qpAVvTHPNeTYi650k6vUmfuKER1 /stq7FsGVOgD4H8y6HXHhx2mncKZPC/Ow46mwXPO3OA33Q7/XwFX+mXYOCs0hQQDjLllnbpovnm z X-Google-Smtp-Source: AGHT+IFqP0V73sB6yfhjktcYXvSJboQOTPivuDgWoV7koQyR3H6YF+YDzabSmStSgs1/Jx1z2mphcg== X-Received: by 2002:a17:907:e8d:b0:a86:80ef:4fe5 with SMTP id a640c23a62f3a-a9029617930mr2336028666b.47.1726672919470; Wed, 18 Sep 2024 08:21:59 -0700 (PDT) Received: from fedora.sec.9e.network (ip-037-049-067-221.um09.pools.vodafone-ip.de. [37.49.67.221]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a90610967b0sm599791266b.42.2024.09.18.08.21.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Sep 2024 08:21:59 -0700 (PDT) From: Patrick Rudolph To: u-boot@lists.denx.de, Simon Glass Cc: Maximilian Brune , Patrick Rudolph , Bin Meng , Tom Rini Subject: [PATCH v4 01/35] acpi: x86: Move SPCR and DBG2 into common code Date: Wed, 18 Sep 2024 17:20:05 +0200 Message-ID: <20240918152136.3395170-2-patrick.rudolph@9elements.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240918152136.3395170-1-patrick.rudolph@9elements.com> References: <20240918152136.3395170-1-patrick.rudolph@9elements.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Maximilian Brune This moves the SPCR and DBG2 table generation into common code, so that they can be used by architectures other than x86. Signed-off-by: Maximilian Brune Signed-off-by: Patrick Rudolph Reviewed-by: Simon Glass Cc: Simon Glass Cc: Bin Meng --- Changelog v2: - Do not add new features, just move code and make it compile on 64bit. --- arch/x86/include/asm/acpi_table.h | 11 -- arch/x86/lib/acpi_table.c | 174 ---------------------------- include/acpi/acpi_table.h | 11 ++ lib/acpi/acpi_table.c | 184 ++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 185 deletions(-) diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index 57e41654ce..e617524617 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -45,17 +45,6 @@ int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, */ int acpi_write_hpet(struct acpi_ctx *ctx); -/** - * acpi_write_dbg2_pci_uart() - Write out a DBG2 table - * - * @ctx: Current ACPI context - * @dev: Debug UART device to describe - * @access_size: Access size for UART (e.g. ACPI_ACCESS_SIZE_DWORD_ACCESS) - * Return: 0 if OK, -ve on error - */ -int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, - uint access_size); - /** * acpi_create_gnvs() - Create a GNVS (Global Non Volatile Storage) table * diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index e38ce19ff7..08fd1e54ce 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -279,140 +279,6 @@ static int acpi_write_tpm2(struct acpi_ctx *ctx, } ACPI_WRITER(5tpm2, "TPM2", acpi_write_tpm2, 0); -int acpi_write_spcr(struct acpi_ctx *ctx, const struct acpi_writer *entry) -{ - struct serial_device_info serial_info = {0}; - ulong serial_address, serial_offset; - struct acpi_table_header *header; - struct acpi_spcr *spcr; - struct udevice *dev; - uint serial_config; - uint serial_width; - int access_size; - int space_id; - int ret = -ENODEV; - - spcr = ctx->current; - header = &spcr->header; - - memset(spcr, '\0', sizeof(struct acpi_spcr)); - - /* Fill out header fields */ - acpi_fill_header(header, "SPCR"); - header->length = sizeof(struct acpi_spcr); - header->revision = 2; - - /* Read the device once, here. It is reused below */ - dev = gd->cur_serial_dev; - if (dev) - ret = serial_getinfo(dev, &serial_info); - if (ret) - serial_info.type = SERIAL_CHIP_UNKNOWN; - - /* Encode chip type */ - switch (serial_info.type) { - case SERIAL_CHIP_16550_COMPATIBLE: - spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE; - break; - case SERIAL_CHIP_UNKNOWN: - default: - spcr->interface_type = ACPI_DBG2_UNKNOWN; - break; - } - - /* Encode address space */ - switch (serial_info.addr_space) { - case SERIAL_ADDRESS_SPACE_MEMORY: - space_id = ACPI_ADDRESS_SPACE_MEMORY; - break; - case SERIAL_ADDRESS_SPACE_IO: - default: - space_id = ACPI_ADDRESS_SPACE_IO; - break; - } - - serial_width = serial_info.reg_width * 8; - serial_offset = serial_info.reg_offset << serial_info.reg_shift; - serial_address = serial_info.addr + serial_offset; - - /* Encode register access size */ - switch (serial_info.reg_shift) { - case 0: - access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; - break; - case 1: - access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; - break; - case 2: - access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; - break; - case 3: - access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS; - break; - default: - access_size = ACPI_ACCESS_SIZE_UNDEFINED; - break; - } - - debug("UART type %u @ %lx\n", spcr->interface_type, serial_address); - - /* Fill GAS */ - spcr->serial_port.space_id = space_id; - spcr->serial_port.bit_width = serial_width; - spcr->serial_port.bit_offset = 0; - spcr->serial_port.access_size = access_size; - spcr->serial_port.addrl = lower_32_bits(serial_address); - spcr->serial_port.addrh = upper_32_bits(serial_address); - - /* Encode baud rate */ - switch (serial_info.baudrate) { - case 9600: - spcr->baud_rate = 3; - break; - case 19200: - spcr->baud_rate = 4; - break; - case 57600: - spcr->baud_rate = 6; - break; - case 115200: - spcr->baud_rate = 7; - break; - default: - spcr->baud_rate = 0; - break; - } - - serial_config = SERIAL_DEFAULT_CONFIG; - if (dev) - ret = serial_getconfig(dev, &serial_config); - - spcr->parity = SERIAL_GET_PARITY(serial_config); - spcr->stop_bits = SERIAL_GET_STOP(serial_config); - - /* No PCI devices for now */ - spcr->pci_device_id = 0xffff; - spcr->pci_vendor_id = 0xffff; - - /* - * SPCR has no clue if the UART base clock speed is different - * to the default one. However, the SPCR 1.04 defines baud rate - * 0 as a preconfigured state of UART and OS is supposed not - * to touch the configuration of the serial device. - */ - if (serial_info.clock != SERIAL_DEFAULT_CLOCK) - spcr->baud_rate = 0; - - /* Fix checksum */ - header->checksum = table_compute_checksum((void *)spcr, header->length); - - acpi_add_table(ctx, spcr); - acpi_inc(ctx, spcr->header.length); - - return 0; -} -ACPI_WRITER(5spcr, "SPCR", acpi_write_spcr, 0); - int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) { ulong addr; @@ -515,46 +381,6 @@ int acpi_write_hpet(struct acpi_ctx *ctx) return 0; } -int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, - uint access_size) -{ - struct acpi_dbg2_header *dbg2 = ctx->current; - char path[ACPI_PATH_MAX]; - struct acpi_gen_regaddr address; - phys_addr_t addr; - int ret; - - if (!device_active(dev)) { - log_info("Device not enabled\n"); - return -EACCES; - } - /* - * PCI devices don't remember their resource allocation information in - * U-Boot at present. We assume that MMIO is used for the UART and that - * the address space is 32 bytes: ns16550 uses 8 registers of up to - * 32-bits each. This is only for debugging so it is not a big deal. - */ - addr = dm_pci_read_bar32(dev, 0); - log_debug("UART addr %lx\n", (ulong)addr); - - memset(&address, '\0', sizeof(address)); - address.space_id = ACPI_ADDRESS_SPACE_MEMORY; - address.addrl = (uint32_t)addr; - address.addrh = (uint32_t)((addr >> 32) & 0xffffffff); - address.access_size = access_size; - - ret = acpi_device_path(dev, path, sizeof(path)); - if (ret) - return log_msg_ret("path", ret); - acpi_create_dbg2(dbg2, ACPI_DBG2_SERIAL_PORT, - ACPI_DBG2_16550_COMPATIBLE, &address, 0x1000, path); - - acpi_inc_align(ctx, dbg2->header.length); - acpi_add_table(ctx, dbg2); - - return 0; -} - void acpi_fadt_common(struct acpi_fadt *fadt, struct acpi_facs *facs, void *dsdt) { diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index 15fd61a51d..a372435492 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -913,6 +913,17 @@ static inline int acpi_add_fadt(struct acpi_ctx *ctx, struct acpi_fadt *fadt) return 0; } +/** + * acpi_write_dbg2_pci_uart() - Write out a DBG2 table + * + * @ctx: Current ACPI context + * @dev: Debug UART device to describe + * @access_size: Access size for UART (e.g. ACPI_ACCESS_SIZE_DWORD_ACCESS) + * Return: 0 if OK, -ve on error + */ +int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, + uint access_size); + /** * acpi_write_rsdp() - Write out an RSDP indicating where the ACPI tables are * diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index 6dbfdb22de..c9ddcca8cb 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -262,3 +264,185 @@ void acpi_create_dbg2(struct acpi_dbg2_header *dbg2, header->length = current - (uintptr_t)dbg2; header->checksum = table_compute_checksum(dbg2, header->length); } + +int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, + uint access_size) +{ + struct acpi_dbg2_header *dbg2 = ctx->current; + char path[ACPI_PATH_MAX]; + struct acpi_gen_regaddr address; + u64 addr; + int ret; + + if (!device_active(dev)) { + log_info("Device not enabled\n"); + return -EACCES; + } + /* + * PCI devices don't remember their resource allocation information in + * U-Boot at present. We assume that MMIO is used for the UART and that + * the address space is 32 bytes: ns16550 uses 8 registers of up to + * 32-bits each. This is only for debugging so it is not a big deal. + */ + addr = dm_pci_read_bar32(dev, 0); + log_debug("UART addr %lx\n", (ulong)addr); + + ret = acpi_device_path(dev, path, sizeof(path)); + if (ret) + return log_msg_ret("path", ret); + + memset(&address, '\0', sizeof(address)); + address.space_id = ACPI_ADDRESS_SPACE_MEMORY; + address.addrl = (uint32_t)addr; + address.addrh = (uint32_t)((addr >> 32) & 0xffffffff); + address.access_size = access_size; + + ret = acpi_device_path(dev, path, sizeof(path)); + if (ret) + return log_msg_ret("path", ret); + acpi_create_dbg2(dbg2, ACPI_DBG2_SERIAL_PORT, + ACPI_DBG2_16550_COMPATIBLE, &address, 0x1000, path); + + acpi_inc_align(ctx, dbg2->header.length); + acpi_add_table(ctx, dbg2); + + return 0; +} + +static int acpi_write_spcr(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct serial_device_info serial_info = {0}; + ulong serial_address, serial_offset; + struct acpi_table_header *header; + struct acpi_spcr *spcr; + struct udevice *dev; + uint serial_config; + uint serial_width; + int access_size; + int space_id; + int ret = -ENODEV; + + spcr = ctx->current; + header = &spcr->header; + + memset(spcr, '\0', sizeof(struct acpi_spcr)); + + /* Fill out header fields */ + acpi_fill_header(header, "SPCR"); + header->length = sizeof(struct acpi_spcr); + header->revision = 2; + + /* Read the device once, here. It is reused below */ + dev = gd->cur_serial_dev; + if (dev) + ret = serial_getinfo(dev, &serial_info); + if (ret) + serial_info.type = SERIAL_CHIP_UNKNOWN; + + /* Encode chip type */ + switch (serial_info.type) { + case SERIAL_CHIP_16550_COMPATIBLE: + spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE; + break; + case SERIAL_CHIP_PL01X: + spcr->interface_type = ACPI_DBG2_ARM_PL011; + break; + case SERIAL_CHIP_UNKNOWN: + default: + spcr->interface_type = ACPI_DBG2_UNKNOWN; + break; + } + + /* Encode address space */ + switch (serial_info.addr_space) { + case SERIAL_ADDRESS_SPACE_MEMORY: + space_id = ACPI_ADDRESS_SPACE_MEMORY; + break; + case SERIAL_ADDRESS_SPACE_IO: + default: + space_id = ACPI_ADDRESS_SPACE_IO; + break; + } + + serial_width = serial_info.reg_width * 8; + serial_offset = serial_info.reg_offset << serial_info.reg_shift; + serial_address = serial_info.addr + serial_offset; + + /* Encode register access size */ + switch (serial_info.reg_shift) { + case 0: + access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; + break; + case 1: + access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; + break; + case 2: + access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + break; + case 3: + access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS; + break; + default: + access_size = ACPI_ACCESS_SIZE_UNDEFINED; + break; + } + + debug("UART type %u @ %lx\n", spcr->interface_type, serial_address); + + /* Fill GAS */ + spcr->serial_port.space_id = space_id; + spcr->serial_port.bit_width = serial_width; + spcr->serial_port.bit_offset = 0; + spcr->serial_port.access_size = access_size; + spcr->serial_port.addrl = lower_32_bits(serial_address); + spcr->serial_port.addrh = upper_32_bits(serial_address); + + /* Encode baud rate */ + switch (serial_info.baudrate) { + case 9600: + spcr->baud_rate = 3; + break; + case 19200: + spcr->baud_rate = 4; + break; + case 57600: + spcr->baud_rate = 6; + break; + case 115200: + spcr->baud_rate = 7; + break; + default: + spcr->baud_rate = 0; + break; + } + + serial_config = SERIAL_DEFAULT_CONFIG; + if (dev) + ret = serial_getconfig(dev, &serial_config); + + spcr->parity = SERIAL_GET_PARITY(serial_config); + spcr->stop_bits = SERIAL_GET_STOP(serial_config); + + /* No PCI devices for now */ + spcr->pci_device_id = 0xffff; + spcr->pci_vendor_id = 0xffff; + + /* + * SPCR has no clue if the UART base clock speed is different + * to the default one. However, the SPCR 1.04 defines baud rate + * 0 as a preconfigured state of UART and OS is supposed not + * to touch the configuration of the serial device. + */ + if (serial_info.clock != SERIAL_DEFAULT_CLOCK) + spcr->baud_rate = 0; + + /* Fix checksum */ + header->checksum = table_compute_checksum((void *)spcr, header->length); + + acpi_add_table(ctx, spcr); + acpi_inc(ctx, spcr->header.length); + + return 0; +} + +ACPI_WRITER(5spcr, "SPCR", acpi_write_spcr, 0); -- 2.46.0