build: Implement CONFIGDIR setting

In effort to support different builds of Aimee OS using the same
scripts, without necessarily having to fork this repository, the build
system now supports a `CONFIGDIR` setting.  When this variable is set,
files defining the target environment, such as the lists of packages to
install, the kernel configuration, the Portage configuration, etc. are
found in the path it specifes.

The reference build, for the Home Assistant Yellow board, is configured
in the `yellow` directory.  To build it, run:

```sh
CONFIGDIR=yellow ./vm-build.sh
```
This commit is contained in:
2023-03-13 16:21:20 -05:00
parent 1914b3aba0
commit 31d8a98f64
100 changed files with 83 additions and 53 deletions

View File

@@ -0,0 +1,54 @@
From 85fb54b621c1ca79f1ec8634b0597a038338e51d Mon Sep 17 00:00:00 2001
Message-Id: <85fb54b621c1ca79f1ec8634b0597a038338e51d.1668448114.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Thu, 14 Apr 2022 12:15:26 +0200
Subject: [PATCH] drivers: bcm283x: don't explicitly disable init
It seems that the reason why init doesn't succeed is the lack of clock
support in U-Boot. Setting the default clock of 48MHz for the PL011
UARTs makes reinitialization work consistently.
Note that for the first UART the "skip-init" is anyways set in the
device tree. This will only affect probing of UARTs not enabled by
firmware.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/serial/serial_bcm283x_pl011.c | 6 ------
include/configs/rpi.h | 3 +++
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/serial/serial_bcm283x_pl011.c b/drivers/serial/serial_bcm283x_pl011.c
index 7d172cdac0..fcba07f1c5 100644
--- a/drivers/serial/serial_bcm283x_pl011.c
+++ b/drivers/serial/serial_bcm283x_pl011.c
@@ -51,12 +51,6 @@ static int bcm283x_pl011_serial_probe(struct udevice *dev)
if (ret)
return ret;
- /*
- * TODO: Reinitialization doesn't always work for now, just skip
- * init always - we know we're already initialized
- */
- plat->skip_init = true;
-
return pl01x_serial_probe(dev);
}
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index 7257659932..7fdf2a891d 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -33,6 +33,9 @@
*/
#define CONFIG_SYS_SDRAM_SIZE SZ_128M
+/* Define PL011 default clock */
+#define CONFIG_PL011_CLOCK 48000000
+
/* Devices */
/* LCD */
--
2.38.1

View File

@@ -0,0 +1,83 @@
From 135d886b4e5077c8fa96a5449a70d81ae9c1c3d0 Mon Sep 17 00:00:00 2001
Message-Id: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
From: Pascal Vizeli <pvizeli@syshack.ch>
Date: Tue, 10 Dec 2019 09:48:46 +0000
Subject: [PATCH] rpi: Use CONFIG_OF_BOARD instead of CONFIG_EMBED
Signed-off-by: Pascal Vizeli <pvizeli@syshack.ch>
---
configs/rpi_0_w_defconfig | 2 +-
configs/rpi_2_defconfig | 2 +-
configs/rpi_3_32b_defconfig | 2 +-
configs/rpi_3_defconfig | 2 +-
configs/rpi_defconfig | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/configs/rpi_0_w_defconfig b/configs/rpi_0_w_defconfig
index baa8c37810..f20aa164e5 100644
--- a/configs/rpi_0_w_defconfig
+++ b/configs/rpi_0_w_defconfig
@@ -23,7 +23,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_FS_UUID=y
-CONFIG_OF_EMBED=y
+CONFIG_OF_BOARD=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig
index baae6d4871..60987ad91a 100644
--- a/configs/rpi_2_defconfig
+++ b/configs/rpi_2_defconfig
@@ -24,7 +24,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_FS_UUID=y
-CONFIG_OF_EMBED=y
+CONFIG_OF_BOARD=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
diff --git a/configs/rpi_3_32b_defconfig b/configs/rpi_3_32b_defconfig
index f51f3de596..e6de8669d0 100644
--- a/configs/rpi_3_32b_defconfig
+++ b/configs/rpi_3_32b_defconfig
@@ -23,7 +23,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_FS_UUID=y
-CONFIG_OF_EMBED=y
+CONFIG_OF_BOARD=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
diff --git a/configs/rpi_3_defconfig b/configs/rpi_3_defconfig
index bc1a318db4..70f4f8ed70 100644
--- a/configs/rpi_3_defconfig
+++ b/configs/rpi_3_defconfig
@@ -22,7 +22,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_FS_UUID=y
-CONFIG_OF_EMBED=y
+CONFIG_OF_BOARD=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
diff --git a/configs/rpi_defconfig b/configs/rpi_defconfig
index 1d356b4b2e..6f345c790b 100644
--- a/configs/rpi_defconfig
+++ b/configs/rpi_defconfig
@@ -23,7 +23,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_FS_UUID=y
-CONFIG_OF_EMBED=y
+CONFIG_OF_BOARD=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
--
2.38.1

View File

@@ -0,0 +1,68 @@
From 921f4b6d8cb3b997dd5c54fd436bb8223046421e Mon Sep 17 00:00:00 2001
Message-Id: <921f4b6d8cb3b997dd5c54fd436bb8223046421e.1668448114.git.stefan@agner.ch>
In-Reply-To: <85fb54b621c1ca79f1ec8634b0597a038338e51d.1668448114.git.stefan@agner.ch>
References: <85fb54b621c1ca79f1ec8634b0597a038338e51d.1668448114.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Thu, 14 Apr 2022 12:18:41 +0200
Subject: [PATCH] drivers: bcm283x: allow to spawn any PL011 UART
The current code checks pinmux for the first PL011 only. Raspberry Pi 4
has multiple PL011 UARTs. This code prevents probing of other UARTs in
case the first PL011 UART is not active.
Furthermore, U-Boot supports pinmuxing, hence the pins should be muxed
at this point anyway. Drop the check entirly.
This allows to use other UARTs as stdout paths (e.g. stdout-path =
"serial5:115200n8").
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/serial/serial_bcm283x_pl011.c | 27 ---------------------------
1 file changed, 27 deletions(-)
diff --git a/drivers/serial/serial_bcm283x_pl011.c b/drivers/serial/serial_bcm283x_pl011.c
index fcba07f1c5..98628e1ca4 100644
--- a/drivers/serial/serial_bcm283x_pl011.c
+++ b/drivers/serial/serial_bcm283x_pl011.c
@@ -11,37 +11,10 @@
#include <serial.h>
#include "serial_pl01x_internal.h"
-/*
- * Check if this serial device is muxed
- *
- * The serial device will only work properly if it has been muxed to the serial
- * pins by firmware. Check whether that happened here.
- *
- * Return: true if serial device is muxed, false if not
- */
-static bool bcm283x_is_serial_muxed(void)
-{
- int serial_gpio = 15;
- struct udevice *dev;
-
- if (uclass_first_device_err(UCLASS_PINCTRL, &dev))
- return false;
-
- if (pinctrl_get_gpio_mux(dev, 0, serial_gpio) != BCM2835_GPIO_ALT0)
- return false;
-
- return true;
-}
-
static int bcm283x_pl011_serial_probe(struct udevice *dev)
{
- struct pl01x_serial_plat *plat = dev_get_plat(dev);
int ret;
- /* Don't spawn the device if it's not muxed */
- if (!bcm283x_is_serial_muxed())
- return -ENODEV;
-
/*
* Read the ofdata here rather than in an of_to_plat() method
* since we need the soc simple-bus to be probed so that the 'ranges'
--
2.38.1

View File

@@ -0,0 +1,44 @@
From 191b5f4e0408e40f35379fdaab6b37a7ad93e298 Mon Sep 17 00:00:00 2001
Message-Id: <191b5f4e0408e40f35379fdaab6b37a7ad93e298.1668448794.git.stefan@agner.ch>
In-Reply-To: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
References: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Tue, 29 Dec 2020 23:34:52 +0100
Subject: [PATCH] rpi: add NVMe to boot order
The Compute Module 4 I/O Board can support a NVMe. Add NVMe to the boot
order.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
include/configs/rpi.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index cd8fe8b518..7257659932 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -131,6 +131,12 @@
#define BOOT_TARGET_MMC(func)
#endif
+#if CONFIG_IS_ENABLED(CMD_NVME)
+ #define BOOT_TARGET_NVME(func) func(NVME, nvme, 0)
+#else
+ #define BOOT_TARGET_NVME(func)
+#endif
+
#if CONFIG_IS_ENABLED(CMD_USB)
#define BOOT_TARGET_USB(func) func(USB, usb, 0)
#else
@@ -151,6 +157,7 @@
#define BOOT_TARGET_DEVICES(func) \
BOOT_TARGET_MMC(func) \
+ BOOT_TARGET_NVME(func) \
BOOT_TARGET_USB(func) \
BOOT_TARGET_PXE(func) \
BOOT_TARGET_DHCP(func)
--
2.38.1

View File

@@ -0,0 +1,43 @@
From 644bd3743aa8771ef7ecb7b7239308d6da2a5b35 Mon Sep 17 00:00:00 2001
Message-Id: <644bd3743aa8771ef7ecb7b7239308d6da2a5b35.1668448794.git.stefan@agner.ch>
In-Reply-To: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
References: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Thu, 23 Sep 2021 23:43:31 +0200
Subject: [PATCH] Revert "nvme: Correct the prps per page calculation method"
This reverts commit 859b33c948945f7904f60a2c12a3792d356d51ad.
If there is more than one PRP List the last entry is a pointer to
the next list. From the NVM Express specification:
"The last entry within a memory page, as indicated by the memory page
size in the CC.MPS field, shall be a PRP List pointer if there is more
than a single memory page of data to be transferred."
For the purpose of calculating the number of pages required for PRP
lists we should always assume that the last entry is required for
the next PRP list.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Cc: Wesley Sheng <wesleyshenggit@sina.com>
---
drivers/nvme/nvme.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 6d0d3f3ca2..73db80a294 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -52,7 +52,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
u64 *prp_pool;
int length = total_len;
int i, nprps;
- u32 prps_per_page = page_size >> 3;
+ u32 prps_per_page = (page_size >> 3) - 1;
u32 num_pages;
length -= (page_size - offset);
--
2.38.1

View File

@@ -0,0 +1,33 @@
From de29ca70117fb2bfafa8b5699b34e9e94560b785 Mon Sep 17 00:00:00 2001
Message-Id: <de29ca70117fb2bfafa8b5699b34e9e94560b785.1668448794.git.stefan@agner.ch>
In-Reply-To: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
References: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Thu, 7 Oct 2021 12:02:39 +0200
Subject: [PATCH] usb: xhci-brcm: Make driver compatible with downstream device
tree
The downstream device tree uses just "generic-xhci" as compatible
string. Use this string to make U-Boot work with the downstream Kernel.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/usb/host/xhci-brcm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-brcm.c b/drivers/usb/host/xhci-brcm.c
index fe17924028..0c6938187b 100644
--- a/drivers/usb/host/xhci-brcm.c
+++ b/drivers/usb/host/xhci-brcm.c
@@ -82,7 +82,7 @@ static int xhci_brcm_deregister(struct udevice *dev)
}
static const struct udevice_id xhci_brcm_ids[] = {
- { .compatible = "brcm,generic-xhci" },
+ { .compatible = "generic-xhci" },
{ }
};
--
2.38.1

View File

@@ -0,0 +1,49 @@
From ab2790f8ff78790ea8a9cb0b05cafc55648ebbc4 Mon Sep 17 00:00:00 2001
Message-Id: <ab2790f8ff78790ea8a9cb0b05cafc55648ebbc4.1668448794.git.stefan@agner.ch>
In-Reply-To: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
References: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Thu, 23 Sep 2021 23:52:44 +0200
Subject: [PATCH] nvme: improve readability of nvme_setup_prps()
Improve readability by introducing consts, reuse consts where
appropriate and adding variables with discriptive name.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/nvme/nvme.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 73db80a294..751abc3cd5 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -47,12 +47,12 @@ static int nvme_wait_csts(struct nvme_dev *dev, u32 mask, u32 val)
static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
int total_len, u64 dma_addr)
{
- u32 page_size = dev->page_size;
+ const u32 page_size = dev->page_size;
+ const u32 prps_per_page = (page_size >> 3) - 1;
int offset = dma_addr & (page_size - 1);
u64 *prp_pool;
int length = total_len;
int i, nprps;
- u32 prps_per_page = (page_size >> 3) - 1;
u32 num_pages;
length -= (page_size - offset);
@@ -91,8 +91,8 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
i = 0;
while (nprps) {
if ((i == (prps_per_page - 1)) && nprps > 1) {
- *(prp_pool + i) = cpu_to_le64((ulong)prp_pool +
- page_size);
+ u64 next_prp_list = (u64)prp_pool + page_size;
+ *(prp_pool + i) = cpu_to_le64(next_prp_list);
i = 0;
prp_pool += page_size;
}
--
2.38.1

View File

@@ -0,0 +1,264 @@
From 2b508d92673738d837576301866dc234d8b008c4 Mon Sep 17 00:00:00 2001
Message-Id: <2b508d92673738d837576301866dc234d8b008c4.1668448794.git.stefan@agner.ch>
In-Reply-To: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
References: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Thu, 23 Sep 2021 23:58:35 +0200
Subject: [PATCH] nvme: Use pointer for CPU addressed buffers
Pass buffers which use CPU addressing as void pointers. This aligns with
DMA APIs which use void pointers as argument. It will avoid unnecessary
type casts when adding support bus address translations.
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/nvme/nvme.c | 50 ++++++++++++++++++++--------------------
drivers/nvme/nvme_show.c | 4 ++--
include/nvme.h | 12 +++++-----
3 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 751abc3cd5..352c94ea91 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -45,11 +45,11 @@ static int nvme_wait_csts(struct nvme_dev *dev, u32 mask, u32 val)
}
static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
- int total_len, u64 dma_addr)
+ int total_len, void *buffer)
{
const u32 page_size = dev->page_size;
const u32 prps_per_page = (page_size >> 3) - 1;
- int offset = dma_addr & (page_size - 1);
+ int offset = (uintptr_t)buffer & (page_size - 1);
u64 *prp_pool;
int length = total_len;
int i, nprps;
@@ -63,10 +63,10 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
}
if (length)
- dma_addr += (page_size - offset);
+ buffer += (page_size - offset);
if (length <= page_size) {
- *prp2 = dma_addr;
+ *prp2 = (u64)buffer;
return 0;
}
@@ -96,11 +96,11 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
i = 0;
prp_pool += page_size;
}
- *(prp_pool + i++) = cpu_to_le64(dma_addr);
- dma_addr += page_size;
+ *(prp_pool + i++) = cpu_to_le64((u64)buffer);
+ buffer += page_size;
nprps--;
}
- *prp2 = (ulong)dev->prp_pool;
+ *prp2 = (u64)dev->prp_pool;
flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
num_pages * page_size);
@@ -447,42 +447,42 @@ static int nvme_alloc_sq(struct nvme_dev *dev, u16 qid,
}
int nvme_identify(struct nvme_dev *dev, unsigned nsid,
- unsigned cns, dma_addr_t dma_addr)
+ unsigned int cns, void *buffer)
{
struct nvme_command c;
u32 page_size = dev->page_size;
- int offset = dma_addr & (page_size - 1);
+ int offset = (uintptr_t)buffer & (page_size - 1);
int length = sizeof(struct nvme_id_ctrl);
int ret;
memset(&c, 0, sizeof(c));
c.identify.opcode = nvme_admin_identify;
c.identify.nsid = cpu_to_le32(nsid);
- c.identify.prp1 = cpu_to_le64(dma_addr);
+ c.identify.prp1 = cpu_to_le64((u64)buffer);
length -= (page_size - offset);
if (length <= 0) {
c.identify.prp2 = 0;
} else {
- dma_addr += (page_size - offset);
- c.identify.prp2 = cpu_to_le64(dma_addr);
+ buffer += (page_size - offset);
+ c.identify.prp2 = cpu_to_le64((u64)buffer);
}
c.identify.cns = cpu_to_le32(cns);
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ invalidate_dcache_range((uintptr_t)buffer,
+ (uintptr_t)buffer + sizeof(struct nvme_id_ctrl));
ret = nvme_submit_admin_cmd(dev, &c, NULL);
if (!ret)
- invalidate_dcache_range(dma_addr,
- dma_addr + sizeof(struct nvme_id_ctrl));
+ invalidate_dcache_range((uintptr_t)buffer,
+ (uintptr_t)buffer + sizeof(struct nvme_id_ctrl));
return ret;
}
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
- dma_addr_t dma_addr, u32 *result)
+ void *buffer, u32 *result)
{
struct nvme_command c;
int ret;
@@ -490,7 +490,7 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
memset(&c, 0, sizeof(c));
c.features.opcode = nvme_admin_get_features;
c.features.nsid = cpu_to_le32(nsid);
- c.features.prp1 = cpu_to_le64(dma_addr);
+ c.features.prp1 = cpu_to_le64((u64)buffer);
c.features.fid = cpu_to_le32(fid);
ret = nvme_submit_admin_cmd(dev, &c, result);
@@ -510,13 +510,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
}
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
- dma_addr_t dma_addr, u32 *result)
+ void *buffer, u32 *result)
{
struct nvme_command c;
memset(&c, 0, sizeof(c));
c.features.opcode = nvme_admin_set_features;
- c.features.prp1 = cpu_to_le64(dma_addr);
+ c.features.prp1 = cpu_to_le64((u64)buffer);
c.features.fid = cpu_to_le32(fid);
c.features.dword11 = cpu_to_le32(dword11);
@@ -567,7 +567,7 @@ static int nvme_set_queue_count(struct nvme_dev *dev, int count)
u32 q_count = (count - 1) | ((count - 1) << 16);
status = nvme_set_features(dev, NVME_FEAT_NUM_QUEUES,
- q_count, 0, &result);
+ q_count, NULL, &result);
if (status < 0)
return status;
@@ -619,7 +619,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev)
if (!ctrl)
return -ENOMEM;
- ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl);
+ ret = nvme_identify(dev, 0, 1, ctrl);
if (ret) {
free(ctrl);
return -EIO;
@@ -704,7 +704,7 @@ static int nvme_blk_probe(struct udevice *udev)
ns->dev = ndev;
/* extract the namespace id from the block device name */
ns->ns_id = trailing_strtol(udev->name);
- if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) {
+ if (nvme_identify(ndev, ns->ns_id, 0, id)) {
free(id);
return -EIO;
}
@@ -738,7 +738,7 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
u64 prp2;
u64 total_len = blkcnt << desc->log2blksz;
u64 temp_len = total_len;
- uintptr_t temp_buffer = (uintptr_t)buffer;
+ void *temp_buffer = buffer;
u64 slba = blknr;
u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift);
@@ -872,7 +872,7 @@ int nvme_init(struct udevice *udev)
char name[20];
memset(id, 0, sizeof(*id));
- if (nvme_identify(ndev, i, 0, (dma_addr_t)(long)id)) {
+ if (nvme_identify(ndev, i, 0, id)) {
ret = -EIO;
goto free_id;
}
diff --git a/drivers/nvme/nvme_show.c b/drivers/nvme/nvme_show.c
index 72cbac82bc..ac9b5cc9bd 100644
--- a/drivers/nvme/nvme_show.c
+++ b/drivers/nvme/nvme_show.c
@@ -114,7 +114,7 @@ int nvme_print_info(struct udevice *udev)
if (!ctrl)
return -ENOMEM;
- if (nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl)) {
+ if (nvme_identify(dev, 0, 1, ctrl)) {
ret = -EIO;
goto free_ctrl;
}
@@ -129,7 +129,7 @@ int nvme_print_info(struct udevice *udev)
goto free_ctrl;
}
- if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)(long)id)) {
+ if (nvme_identify(dev, ns->ns_id, 0, id)) {
ret = -EIO;
goto free_id;
}
diff --git a/include/nvme.h b/include/nvme.h
index 2cdf8ce320..8ff823cd81 100644
--- a/include/nvme.h
+++ b/include/nvme.h
@@ -18,12 +18,12 @@ struct nvme_dev;
* @dev: NVMe controller device
* @nsid: 0 for controller, namespace id for namespace to identify
* @cns: 1 for controller, 0 for namespace
- * @dma_addr: dma buffer address to store the identify result
+ * @buffer: dma buffer address to store the identify result
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
* -EIO on command execution fails
*/
int nvme_identify(struct nvme_dev *dev, unsigned nsid,
- unsigned cns, dma_addr_t dma_addr);
+ unsigned int cns, void *buffer);
/**
* nvme_get_features - retrieve the attributes of the feature specified
@@ -33,13 +33,13 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
* @dev: NVMe controller device
* @fid: feature id to provide data
* @nsid: namespace id the command applies to
- * @dma_addr: data structure used as part of the specified feature
+ * @buffer: data structure used as part of the specified feature
* @result: command-specific result in the completion queue entry
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
* -EIO on command execution fails
*/
int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
- dma_addr_t dma_addr, u32 *result);
+ void *buffer, u32 *result);
/**
* nvme_set_features - specify the attributes of the feature indicated
@@ -49,13 +49,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
* @dev: NVMe controller device
* @fid: feature id to provide data
* @dword11: command-specific input parameter
- * @dma_addr: data structure used as part of the specified feature
+ * @buffer: data structure used as part of the specified feature
* @result: command-specific result in the completion queue entry
* @return: 0 on success, -ETIMEDOUT on command execution timeout,
* -EIO on command execution fails
*/
int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
- dma_addr_t dma_addr, u32 *result);
+ void *buffer, u32 *result);
/**
* nvme_scan_namespace - scan all namespaces attached to NVMe controllers
--
2.38.1

View File

@@ -0,0 +1,176 @@
From c70926d8b8ad11b8e489e92a8ca9ca93fb201595 Mon Sep 17 00:00:00 2001
Message-Id: <c70926d8b8ad11b8e489e92a8ca9ca93fb201595.1668448794.git.stefan@agner.ch>
In-Reply-To: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
References: <135d886b4e5077c8fa96a5449a70d81ae9c1c3d0.1668448794.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Fri, 24 Sep 2021 00:27:39 +0200
Subject: [PATCH] nvme: translate virtual addresses into the bus's address
space
So far we've been content with passing physical/CPU addresses when
configuring memory addresses into NVMe controllers, but not all
platforms have buses with transparent mappings. Specifically the
Raspberry Pi 4 might introduce an offset to memory accesses incoming
from its PCIe port.
Introduce nvme_virt_to_bus() and nvme_bus_to_virt() to cater with these
limitations, and make sure we don't break non DM users.
For devices where PCIe's view of host memory doesn't match the memory
as seen by the CPU.
A similar change has been introduced for XHCI controller with
commit 1a474559d90a ("xhci: translate virtual addresses into the bus's
address space").
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
drivers/nvme/nvme.c | 31 +++++++++++++++++--------------
drivers/nvme/nvme.h | 8 ++++++++
2 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 352c94ea91..fdfc49677b 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -66,7 +66,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
buffer += (page_size - offset);
if (length <= page_size) {
- *prp2 = (u64)buffer;
+ *prp2 = nvme_virt_to_bus(dev, buffer);
return 0;
}
@@ -91,16 +91,16 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
i = 0;
while (nprps) {
if ((i == (prps_per_page - 1)) && nprps > 1) {
- u64 next_prp_list = (u64)prp_pool + page_size;
- *(prp_pool + i) = cpu_to_le64(next_prp_list);
+ u64 next = nvme_virt_to_bus(dev, prp_pool + page_size);
+ *(prp_pool + i) = cpu_to_le64(next);
i = 0;
prp_pool += page_size;
}
- *(prp_pool + i++) = cpu_to_le64((u64)buffer);
+ *(prp_pool + i++) = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
buffer += page_size;
nprps--;
}
- *prp2 = (u64)dev->prp_pool;
+ *prp2 = nvme_virt_to_bus(dev, dev->prp_pool);
flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
num_pages * page_size);
@@ -353,6 +353,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
int result;
u32 aqa;
u64 cap = dev->cap;
+ u64 dma_addr;
struct nvme_queue *nvmeq;
/* most architectures use 4KB as the page size */
unsigned page_shift = 12;
@@ -393,8 +394,10 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
writel(aqa, &dev->bar->aqa);
- nvme_writeq((ulong)nvmeq->sq_cmds, &dev->bar->asq);
- nvme_writeq((ulong)nvmeq->cqes, &dev->bar->acq);
+ dma_addr = nvme_virt_to_bus(dev, nvmeq->sq_cmds);
+ nvme_writeq(dma_addr, &dev->bar->asq);
+ dma_addr = nvme_virt_to_bus(dev, nvmeq->cqes);
+ nvme_writeq(dma_addr, &dev->bar->acq);
result = nvme_enable_ctrl(dev);
if (result)
@@ -420,7 +423,7 @@ static int nvme_alloc_cq(struct nvme_dev *dev, u16 qid,
memset(&c, 0, sizeof(c));
c.create_cq.opcode = nvme_admin_create_cq;
- c.create_cq.prp1 = cpu_to_le64((ulong)nvmeq->cqes);
+ c.create_cq.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, nvmeq->cqes));
c.create_cq.cqid = cpu_to_le16(qid);
c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
c.create_cq.cq_flags = cpu_to_le16(flags);
@@ -437,7 +440,7 @@ static int nvme_alloc_sq(struct nvme_dev *dev, u16 qid,
memset(&c, 0, sizeof(c));
c.create_sq.opcode = nvme_admin_create_sq;
- c.create_sq.prp1 = cpu_to_le64((ulong)nvmeq->sq_cmds);
+ c.create_sq.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, nvmeq->sq_cmds));
c.create_sq.sqid = cpu_to_le16(qid);
c.create_sq.qsize = cpu_to_le16(nvmeq->q_depth - 1);
c.create_sq.sq_flags = cpu_to_le16(flags);
@@ -458,14 +461,14 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid,
memset(&c, 0, sizeof(c));
c.identify.opcode = nvme_admin_identify;
c.identify.nsid = cpu_to_le32(nsid);
- c.identify.prp1 = cpu_to_le64((u64)buffer);
+ c.identify.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
length -= (page_size - offset);
if (length <= 0) {
c.identify.prp2 = 0;
} else {
buffer += (page_size - offset);
- c.identify.prp2 = cpu_to_le64((u64)buffer);
+ c.identify.prp2 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
}
c.identify.cns = cpu_to_le32(cns);
@@ -490,7 +493,7 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid,
memset(&c, 0, sizeof(c));
c.features.opcode = nvme_admin_get_features;
c.features.nsid = cpu_to_le32(nsid);
- c.features.prp1 = cpu_to_le64((u64)buffer);
+ c.features.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
c.features.fid = cpu_to_le32(fid);
ret = nvme_submit_admin_cmd(dev, &c, result);
@@ -516,7 +519,7 @@ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11,
memset(&c, 0, sizeof(c));
c.features.opcode = nvme_admin_set_features;
- c.features.prp1 = cpu_to_le64((u64)buffer);
+ c.features.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer));
c.features.fid = cpu_to_le32(fid);
c.features.dword11 = cpu_to_le32(dword11);
@@ -771,7 +774,7 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
c.rw.slba = cpu_to_le64(slba);
slba += lbas;
c.rw.length = cpu_to_le16(lbas - 1);
- c.rw.prp1 = cpu_to_le64(temp_buffer);
+ c.rw.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, temp_buffer));
c.rw.prp2 = cpu_to_le64(prp2);
status = nvme_submit_sync_cmd(dev->queues[NVME_IO_Q],
&c, NULL, IO_TIMEOUT);
diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h
index bc1d612dde..f52103c009 100644
--- a/drivers/nvme/nvme.h
+++ b/drivers/nvme/nvme.h
@@ -7,8 +7,11 @@
#ifndef __DRIVER_NVME_H__
#define __DRIVER_NVME_H__
+#include <phys2bus.h>
#include <asm/io.h>
+#define nvme_to_dev(_dev) _dev->udev
+
struct nvme_id_power_state {
__le16 max_power; /* centiwatts */
__u8 rsvd2;
@@ -705,4 +708,9 @@ int nvme_init(struct udevice *udev);
*/
int nvme_shutdown(struct udevice *udev);
+static inline dma_addr_t nvme_virt_to_bus(struct nvme_dev *dev, void *addr)
+{
+ return dev_phys_to_bus(nvme_to_dev(dev)->parent, virt_to_phys(addr));
+}
+
#endif /* __DRIVER_NVME_H__ */
--
2.38.1