* [PATCH v3 0/5] Qualcomm SMEM V12 Support
@ 2017-10-11 21:29 Chris Lew
2017-10-11 21:29 ` [PATCH v3 1/5] soc: qcom: smem: Use le32_to_cpu for comparison Chris Lew
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Chris Lew @ 2017-10-11 21:29 UTC (permalink / raw)
To: bjorn.andersson, andy.gross, david.brown
Cc: aneela, linux-arm-msm, linux-soc, linux-kernel, clew, Chris Lew
SMEM V12 was devised to make better use of the global SMEM region. The
global heap region is formatted to be similar to a private partition.
This allows the maximum number of smem items to increase. The maximum
item number is written by the bootloader in a region after the table
of contents. The number of hosts are increased for later chipsets.
This patchset depends on patch: Qualcomm SMEM cached item support.
Chris Lew (5):
soc: qcom: smem: Use le32_to_cpu for comparison
soc: qcom: smem: Read version from the smem header
soc: qcom: smem: Support global partition
soc: qcom: smem: Support dynamic item limit
soc: qcom: smem: Increase the number of hosts
drivers/soc/qcom/smem.c | 250 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 196 insertions(+), 54 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3 1/5] soc: qcom: smem: Use le32_to_cpu for comparison
2017-10-11 21:29 [PATCH v3 0/5] Qualcomm SMEM V12 Support Chris Lew
@ 2017-10-11 21:29 ` Chris Lew
2017-10-12 3:54 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 2/5] soc: qcom: smem: Read version from the smem header Chris Lew
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Chris Lew @ 2017-10-11 21:29 UTC (permalink / raw)
To: bjorn.andersson, andy.gross, david.brown
Cc: aneela, linux-arm-msm, linux-soc, linux-kernel, clew
From: Chris Lew <clew@codeaurora.org>
Endianness can vary in the system, add le32_to_cpu when comparing
partition sizes from smem.
Signed-off-by: Chris Lew <clew@codeaurora.org>
---
Changes since v1:
- New change
Changes since v2:
- Reduce subject to 50 chars and wrap summary to 72 chars
drivers/soc/qcom/smem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index c28275be0038..db04c45d4132 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -698,7 +698,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
return -EINVAL;
}
- if (header->size != entry->size) {
+ if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
dev_err(smem->dev,
"Partition %d has invalid size\n", i);
return -EINVAL;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 2/5] soc: qcom: smem: Read version from the smem header
2017-10-11 21:29 [PATCH v3 0/5] Qualcomm SMEM V12 Support Chris Lew
2017-10-11 21:29 ` [PATCH v3 1/5] soc: qcom: smem: Use le32_to_cpu for comparison Chris Lew
@ 2017-10-11 21:29 ` Chris Lew
2017-10-12 3:56 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 3/5] soc: qcom: smem: Support global partition Chris Lew
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Chris Lew @ 2017-10-11 21:29 UTC (permalink / raw)
To: bjorn.andersson, andy.gross, david.brown
Cc: aneela, linux-arm-msm, linux-soc, linux-kernel, clew
From: Chris Lew <clew@codeaurora.org>
The SMEM header structure includes the version information. Read the
version directly from the header instead of getting an item from the
global heap.
Signed-off-by: Chris Lew <clew@codeaurora.org>
---
Changes since v1:
- Remove unused smem item version macro
- Move smem get version change to separate commit
Changes since v2:
- Reduce subject to 50 chars and wrap summary to 72 chars
drivers/soc/qcom/smem.c | 25 ++++++++-----------------
1 file changed, 8 insertions(+), 17 deletions(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index db04c45d4132..540322ae409e 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -63,13 +63,12 @@
*/
/*
- * Item 3 of the global heap contains an array of versions for the various
- * software components in the SoC. We verify that the boot loader version is
- * what the expected version (SMEM_EXPECTED_VERSION) as a sanity check.
+ * The version member of the smem header contains an array of versions for the
+ * various software components in the SoC. We verify that the boot loader
+ * version is a valid version as a sanity check.
*/
-#define SMEM_ITEM_VERSION 3
-#define SMEM_MASTER_SBL_VERSION_INDEX 7
-#define SMEM_EXPECTED_VERSION 11
+#define SMEM_MASTER_SBL_VERSION_INDEX 7
+#define SMEM_EXPECTED_VERSION 11
/*
* The first 8 items are only to be allocated by the boot loader while
@@ -604,19 +603,11 @@ int qcom_smem_get_free_space(unsigned host)
static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
{
+ struct smem_header *header;
__le32 *versions;
- size_t size;
-
- versions = qcom_smem_get_global(smem, SMEM_ITEM_VERSION, &size);
- if (IS_ERR(versions)) {
- dev_err(smem->dev, "Unable to read the version item\n");
- return -ENOENT;
- }
- if (size < sizeof(unsigned) * SMEM_MASTER_SBL_VERSION_INDEX) {
- dev_err(smem->dev, "Version item is too small\n");
- return -EINVAL;
- }
+ header = smem->regions[0].virt_base;
+ versions = header->version;
return le32_to_cpu(versions[SMEM_MASTER_SBL_VERSION_INDEX]);
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 3/5] soc: qcom: smem: Support global partition
2017-10-11 21:29 [PATCH v3 0/5] Qualcomm SMEM V12 Support Chris Lew
2017-10-11 21:29 ` [PATCH v3 1/5] soc: qcom: smem: Use le32_to_cpu for comparison Chris Lew
2017-10-11 21:29 ` [PATCH v3 2/5] soc: qcom: smem: Read version from the smem header Chris Lew
@ 2017-10-11 21:29 ` Chris Lew
2017-10-12 3:57 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 4/5] soc: qcom: smem: Support dynamic item limit Chris Lew
2017-10-11 21:29 ` [PATCH v3 5/5] soc: qcom: smem: Increase the number of hosts Chris Lew
4 siblings, 1 reply; 11+ messages in thread
From: Chris Lew @ 2017-10-11 21:29 UTC (permalink / raw)
To: bjorn.andersson, andy.gross, david.brown
Cc: aneela, linux-arm-msm, linux-soc, linux-kernel, clew
From: Chris Lew <clew@codeaurora.org>
SMEM V12 creates a global partition to allocate global smem items from
instead of a global heap. The global partition has the same structure as
a private partition.
Signed-off-by: Chris Lew <clew@codeaurora.org>
---
Changes since v1:
- Move V12 descriptions to top comment
- Add cacheline support to global partition
- Add ptable get helper function
- Move global partition init to version check
Changes since v2:
- Return -ENOENT if partition table does not exist
- Exclude -ENOENT error propagation from enumerate_partitions()
- Reduce subject to 50 chars and wrap summary to 72 chars
drivers/soc/qcom/smem.c | 172 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 142 insertions(+), 30 deletions(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 540322ae409e..6a3134e9c591 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -55,6 +55,10 @@
* is hence the region between the cached and non-cached offsets. The header of
* cached items comes after the data.
*
+ * Version 12 (SMEM_GLOBAL_PART_VERSION) changes the item alloc/get procedure
+ * for the global heap. A new global partition is created from the global heap
+ * region with partition type (SMEM_GLOBAL_HOST) and the max smem item count is
+ * set by the bootloader.
*
* To synchronize allocations in the shared memory heaps a remote spinlock must
* be held - currently lock number 3 of the sfpb or tcsr is used for this on all
@@ -68,7 +72,8 @@
* version is a valid version as a sanity check.
*/
#define SMEM_MASTER_SBL_VERSION_INDEX 7
-#define SMEM_EXPECTED_VERSION 11
+#define SMEM_GLOBAL_HEAP_VERSION 11
+#define SMEM_GLOBAL_PART_VERSION 12
/*
* The first 8 items are only to be allocated by the boot loader while
@@ -82,6 +87,9 @@
/* Processor/host identifier for the application processor */
#define SMEM_HOST_APPS 0
+/* Processor/host identifier for the global partition */
+#define SMEM_GLOBAL_HOST 0xfffe
+
/* Max number of processors/hosts in a system */
#define SMEM_HOST_COUNT 9
@@ -230,6 +238,8 @@ struct smem_region {
* struct qcom_smem - device data for the smem device
* @dev: device pointer
* @hwlock: reference to a hwspinlock
+ * @global_partition: pointer to global partition when in use
+ * @global_cacheline: cacheline size for global partition
* @partitions: list of pointers to partitions affecting the current
* processor/host
* @cacheline: list of cacheline sizes for each host
@@ -241,6 +251,8 @@ struct qcom_smem {
struct hwspinlock *hwlock;
+ struct smem_partition_header *global_partition;
+ size_t global_cacheline;
struct smem_partition_header *partitions[SMEM_HOST_COUNT];
size_t cacheline[SMEM_HOST_COUNT];
@@ -317,16 +329,14 @@ static void *cached_entry_to_item(struct smem_private_entry *e)
#define HWSPINLOCK_TIMEOUT 1000
static int qcom_smem_alloc_private(struct qcom_smem *smem,
- unsigned host,
+ struct smem_partition_header *phdr,
unsigned item,
size_t size)
{
- struct smem_partition_header *phdr;
struct smem_private_entry *hdr, *end;
size_t alloc_size;
void *cached;
- phdr = smem->partitions[host];
hdr = phdr_to_first_uncached_entry(phdr);
end = phdr_to_last_uncached_entry(phdr);
cached = phdr_to_last_cached_entry(phdr);
@@ -334,8 +344,8 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
while (hdr < end) {
if (hdr->canary != SMEM_PRIVATE_CANARY) {
dev_err(smem->dev,
- "Found invalid canary in host %d partition\n",
- host);
+ "Found invalid canary in hosts %d:%d partition\n",
+ phdr->host0, phdr->host1);
return -EINVAL;
}
@@ -373,8 +383,8 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
unsigned item,
size_t size)
{
- struct smem_header *header;
struct smem_global_entry *entry;
+ struct smem_header *header;
if (WARN_ON(item >= SMEM_ITEM_COUNT))
return -EINVAL;
@@ -416,6 +426,7 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
*/
int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
{
+ struct smem_partition_header *phdr;
unsigned long flags;
int ret;
@@ -434,10 +445,15 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
if (ret)
return ret;
- if (host < SMEM_HOST_COUNT && __smem->partitions[host])
- ret = qcom_smem_alloc_private(__smem, host, item, size);
- else
+ if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
+ phdr = __smem->partitions[host];
+ ret = qcom_smem_alloc_private(__smem, phdr, item, size);
+ } else if (__smem->global_partition) {
+ phdr = __smem->global_partition;
+ ret = qcom_smem_alloc_private(__smem, phdr, item, size);
+ } else {
ret = qcom_smem_alloc_global(__smem, item, size);
+ }
hwspin_unlock_irqrestore(__smem->hwlock, &flags);
@@ -479,16 +495,12 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
}
static void *qcom_smem_get_private(struct qcom_smem *smem,
- unsigned host,
+ struct smem_partition_header *phdr,
+ size_t cacheline,
unsigned item,
size_t *size)
{
- struct smem_partition_header *phdr;
struct smem_private_entry *e, *end;
- size_t cacheline;
-
- phdr = smem->partitions[host];
- cacheline = smem->cacheline[host];
e = phdr_to_first_uncached_entry(phdr);
end = phdr_to_last_uncached_entry(phdr);
@@ -531,7 +543,8 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
return ERR_PTR(-ENOENT);
invalid_canary:
- dev_err(smem->dev, "Found invalid canary in host %d partition\n", host);
+ dev_err(smem->dev, "Found invalid canary in hosts %d:%d partition\n",
+ phdr->host0, phdr->host1);
return ERR_PTR(-EINVAL);
}
@@ -547,7 +560,9 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
*/
void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
{
+ struct smem_partition_header *phdr;
unsigned long flags;
+ size_t cacheln;
int ret;
void *ptr = ERR_PTR(-EPROBE_DEFER);
@@ -560,10 +575,17 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
if (ret)
return ERR_PTR(ret);
- if (host < SMEM_HOST_COUNT && __smem->partitions[host])
- ptr = qcom_smem_get_private(__smem, host, item, size);
- else
+ if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
+ phdr = __smem->partitions[host];
+ cacheln = __smem->cacheline[host];
+ ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
+ } else if (__smem->global_partition) {
+ phdr = __smem->global_partition;
+ cacheln = __smem->global_cacheline;
+ ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
+ } else {
ptr = qcom_smem_get_global(__smem, item, size);
+ }
hwspin_unlock_irqrestore(__smem->hwlock, &flags);
@@ -592,6 +614,10 @@ int qcom_smem_get_free_space(unsigned host)
phdr = __smem->partitions[host];
ret = le32_to_cpu(phdr->offset_free_cached) -
le32_to_cpu(phdr->offset_free_uncached);
+ } else if (__smem->global_partition) {
+ phdr = __smem->global_partition;
+ ret = le32_to_cpu(phdr->offset_free_cached) -
+ le32_to_cpu(phdr->offset_free_uncached);
} else {
header = __smem->regions[0].virt_base;
ret = le32_to_cpu(header->available);
@@ -612,27 +638,106 @@ static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
return le32_to_cpu(versions[SMEM_MASTER_SBL_VERSION_INDEX]);
}
-static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
- unsigned local_host)
+static struct smem_ptable *qcom_smem_get_ptable(struct qcom_smem *smem)
{
- struct smem_partition_header *header;
- struct smem_ptable_entry *entry;
struct smem_ptable *ptable;
- unsigned remote_host;
- u32 version, host0, host1;
- int i;
+ u32 version;
ptable = smem->regions[0].virt_base + smem->regions[0].size - SZ_4K;
if (memcmp(ptable->magic, SMEM_PTABLE_MAGIC, sizeof(ptable->magic)))
- return 0;
+ return ERR_PTR(-ENOENT);
version = le32_to_cpu(ptable->version);
if (version != 1) {
dev_err(smem->dev,
"Unsupported partition header version %d\n", version);
+ return ERR_PTR(-EINVAL);
+ }
+ return ptable;
+}
+
+static int qcom_smem_set_global_partition(struct qcom_smem *smem)
+{
+ struct smem_partition_header *header;
+ struct smem_ptable_entry *entry = NULL;
+ struct smem_ptable *ptable;
+ u32 host0, host1, size;
+ int i;
+
+ ptable = qcom_smem_get_ptable(smem);
+ if (IS_ERR(ptable))
+ return PTR_ERR(ptable);
+
+ for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
+ entry = &ptable->entry[i];
+ host0 = le16_to_cpu(entry->host0);
+ host1 = le16_to_cpu(entry->host1);
+
+ if (host0 == SMEM_GLOBAL_HOST && host0 == host1)
+ break;
+ }
+
+ if (!entry) {
+ dev_err(smem->dev, "Missing entry for global partition\n");
+ return -EINVAL;
+ }
+
+ if (!le32_to_cpu(entry->offset) || !le32_to_cpu(entry->size)) {
+ dev_err(smem->dev, "Invalid entry for global partition\n");
+ return -EINVAL;
+ }
+
+ if (smem->global_partition) {
+ dev_err(smem->dev, "Already found the global partition\n");
+ return -EINVAL;
+ }
+
+ header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+ host0 = le16_to_cpu(header->host0);
+ host1 = le16_to_cpu(header->host1);
+
+ if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
+ dev_err(smem->dev, "Global partition has invalid magic\n");
+ return -EINVAL;
+ }
+
+ if (host0 != SMEM_GLOBAL_HOST && host1 != SMEM_GLOBAL_HOST) {
+ dev_err(smem->dev, "Global partition hosts are invalid\n");
+ return -EINVAL;
+ }
+
+ if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
+ dev_err(smem->dev, "Global partition has invalid size\n");
return -EINVAL;
}
+ size = le32_to_cpu(header->offset_free_uncached);
+ if (size > le32_to_cpu(header->size)) {
+ dev_err(smem->dev,
+ "Global partition has invalid free pointer\n");
+ return -EINVAL;
+ }
+
+ smem->global_partition = header;
+ smem->global_cacheline = le32_to_cpu(entry->cacheline);
+
+ return 0;
+}
+
+static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
+ unsigned int local_host)
+{
+ struct smem_partition_header *header;
+ struct smem_ptable_entry *entry;
+ struct smem_ptable *ptable;
+ unsigned int remote_host;
+ u32 host0, host1;
+ int i;
+
+ ptable = qcom_smem_get_ptable(smem);
+ if (IS_ERR(ptable))
+ return PTR_ERR(ptable);
+
for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
entry = &ptable->entry[i];
host0 = le16_to_cpu(entry->host0);
@@ -773,13 +878,20 @@ static int qcom_smem_probe(struct platform_device *pdev)
}
version = qcom_smem_get_sbl_version(smem);
- if (version >> 16 != SMEM_EXPECTED_VERSION) {
+ switch (version >> 16) {
+ case SMEM_GLOBAL_PART_VERSION:
+ ret = qcom_smem_set_global_partition(smem);
+ if (ret < 0)
+ return ret;
+ case SMEM_GLOBAL_HEAP_VERSION:
+ break;
+ default:
dev_err(&pdev->dev, "Unsupported SMEM version 0x%x\n", version);
return -EINVAL;
}
ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS);
- if (ret < 0)
+ if (ret < 0 && ret != -ENOENT)
return ret;
hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 4/5] soc: qcom: smem: Support dynamic item limit
2017-10-11 21:29 [PATCH v3 0/5] Qualcomm SMEM V12 Support Chris Lew
` (2 preceding siblings ...)
2017-10-11 21:29 ` [PATCH v3 3/5] soc: qcom: smem: Support global partition Chris Lew
@ 2017-10-11 21:29 ` Chris Lew
2017-10-12 3:58 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 5/5] soc: qcom: smem: Increase the number of hosts Chris Lew
4 siblings, 1 reply; 11+ messages in thread
From: Chris Lew @ 2017-10-11 21:29 UTC (permalink / raw)
To: bjorn.andersson, andy.gross, david.brown
Cc: aneela, linux-arm-msm, linux-soc, linux-kernel, clew
From: Chris Lew <clew@codeaurora.org>
In V12 SMEM, SBL writes SMEM parameter information after the TOC. Use
the SBL provided item count as the max item number.
Signed-off-by: Chris Lew <clew@codeaurora.org>
---
Changes since v1:
- Change num_items to __le16 from __le32
- Move max smem item warning to generic get/alloc functions
- Use get ptable helper function
Changes since v2:
- Rename qcom_smem_get_dynamic_item to qcom_smem_get_item_count
- Reduce subject to 50 chars and wrap summary to 72 chars
drivers/soc/qcom/smem.c | 51 +++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 6a3134e9c591..19704baa65f4 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -223,6 +223,24 @@ struct smem_private_entry {
#define SMEM_PRIVATE_CANARY 0xa5a5
/**
+ * struct smem_info - smem region info located after the table of contents
+ * @magic: magic number, must be SMEM_INFO_MAGIC
+ * @size: size of the smem region
+ * @base_addr: base address of the smem region
+ * @reserved: for now reserved entry
+ * @num_items: highest accepted item number
+ */
+struct smem_info {
+ u8 magic[4];
+ __le32 size;
+ __le32 base_addr;
+ __le32 reserved;
+ __le16 num_items;
+};
+
+static const u8 SMEM_INFO_MAGIC[] = { 0x53, 0x49, 0x49, 0x49 }; /* SIII */
+
+/**
* struct smem_region - representation of a chunk of memory used for smem
* @aux_base: identifier of aux_mem base
* @virt_base: virtual base address of memory with this aux_mem identifier
@@ -243,6 +261,7 @@ struct smem_region {
* @partitions: list of pointers to partitions affecting the current
* processor/host
* @cacheline: list of cacheline sizes for each host
+ * @item_count: max accepted item number
* @num_regions: number of @regions
* @regions: list of the memory regions defining the shared memory
*/
@@ -255,6 +274,7 @@ struct qcom_smem {
size_t global_cacheline;
struct smem_partition_header *partitions[SMEM_HOST_COUNT];
size_t cacheline[SMEM_HOST_COUNT];
+ u32 item_count;
unsigned num_regions;
struct smem_region regions[0];
@@ -386,9 +406,6 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
struct smem_global_entry *entry;
struct smem_header *header;
- if (WARN_ON(item >= SMEM_ITEM_COUNT))
- return -EINVAL;
-
header = smem->regions[0].virt_base;
entry = &header->toc[item];
if (entry->allocated)
@@ -439,6 +456,9 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
return -EINVAL;
}
+ if (WARN_ON(item >= __smem->item_count))
+ return -EINVAL;
+
ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
HWSPINLOCK_TIMEOUT,
&flags);
@@ -471,9 +491,6 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
u32 aux_base;
unsigned i;
- if (WARN_ON(item >= SMEM_ITEM_COUNT))
- return ERR_PTR(-EINVAL);
-
header = smem->regions[0].virt_base;
entry = &header->toc[item];
if (!entry->allocated)
@@ -569,6 +586,9 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
if (!__smem)
return ptr;
+ if (WARN_ON(item >= __smem->item_count))
+ return ERR_PTR(-EINVAL);
+
ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
HWSPINLOCK_TIMEOUT,
&flags);
@@ -656,6 +676,22 @@ static struct smem_ptable *qcom_smem_get_ptable(struct qcom_smem *smem)
return ptable;
}
+static u32 qcom_smem_get_item_count(struct qcom_smem *smem)
+{
+ struct smem_ptable *ptable;
+ struct smem_info *info;
+
+ ptable = qcom_smem_get_ptable(smem);
+ if (IS_ERR_OR_NULL(ptable))
+ return SMEM_ITEM_COUNT;
+
+ info = (struct smem_info *)&ptable->entry[ptable->num_entries];
+ if (memcmp(info->magic, SMEM_INFO_MAGIC, sizeof(info->magic)))
+ return SMEM_ITEM_COUNT;
+
+ return le16_to_cpu(info->num_items);
+}
+
static int qcom_smem_set_global_partition(struct qcom_smem *smem)
{
struct smem_partition_header *header;
@@ -883,7 +919,10 @@ static int qcom_smem_probe(struct platform_device *pdev)
ret = qcom_smem_set_global_partition(smem);
if (ret < 0)
return ret;
+ smem->item_count = qcom_smem_get_item_count(smem);
+ break;
case SMEM_GLOBAL_HEAP_VERSION:
+ smem->item_count = SMEM_ITEM_COUNT;
break;
default:
dev_err(&pdev->dev, "Unsupported SMEM version 0x%x\n", version);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v3 5/5] soc: qcom: smem: Increase the number of hosts
2017-10-11 21:29 [PATCH v3 0/5] Qualcomm SMEM V12 Support Chris Lew
` (3 preceding siblings ...)
2017-10-11 21:29 ` [PATCH v3 4/5] soc: qcom: smem: Support dynamic item limit Chris Lew
@ 2017-10-11 21:29 ` Chris Lew
2017-10-12 3:59 ` Bjorn Andersson
4 siblings, 1 reply; 11+ messages in thread
From: Chris Lew @ 2017-10-11 21:29 UTC (permalink / raw)
To: bjorn.andersson, andy.gross, david.brown
Cc: aneela, linux-arm-msm, linux-soc, linux-kernel, clew
From: Chris Lew <clew@codeaurora.org>
Increase the maximum number of hosts in a system to 10.
Signed-off-by: Chris Lew <clew@codeaurora.org>
---
Changes since v1:
- None
Changes since v2:
- None
drivers/soc/qcom/smem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 19704baa65f4..0b94d62fad2b 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -91,7 +91,7 @@
#define SMEM_GLOBAL_HOST 0xfffe
/* Max number of processors/hosts in a system */
-#define SMEM_HOST_COUNT 9
+#define SMEM_HOST_COUNT 10
/**
* struct smem_proc_comm - proc_comm communication struct (legacy)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3 1/5] soc: qcom: smem: Use le32_to_cpu for comparison
2017-10-11 21:29 ` [PATCH v3 1/5] soc: qcom: smem: Use le32_to_cpu for comparison Chris Lew
@ 2017-10-12 3:54 ` Bjorn Andersson
0 siblings, 0 replies; 11+ messages in thread
From: Bjorn Andersson @ 2017-10-12 3:54 UTC (permalink / raw)
To: Chris Lew
Cc: andy.gross, david.brown, aneela, linux-arm-msm, linux-soc,
linux-kernel, clew
On Wed 11 Oct 14:29 PDT 2017, Chris Lew wrote:
> From: Chris Lew <clew@codeaurora.org>
>
> Endianness can vary in the system, add le32_to_cpu when comparing
> partition sizes from smem.
>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> Signed-off-by: Chris Lew <clew@codeaurora.org>
> ---
>
> Changes since v1:
> - New change
>
> Changes since v2:
> - Reduce subject to 50 chars and wrap summary to 72 chars
>
> drivers/soc/qcom/smem.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> index c28275be0038..db04c45d4132 100644
> --- a/drivers/soc/qcom/smem.c
> +++ b/drivers/soc/qcom/smem.c
> @@ -698,7 +698,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
> return -EINVAL;
> }
>
> - if (header->size != entry->size) {
> + if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
> dev_err(smem->dev,
> "Partition %d has invalid size\n", i);
> return -EINVAL;
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 2/5] soc: qcom: smem: Read version from the smem header
2017-10-11 21:29 ` [PATCH v3 2/5] soc: qcom: smem: Read version from the smem header Chris Lew
@ 2017-10-12 3:56 ` Bjorn Andersson
0 siblings, 0 replies; 11+ messages in thread
From: Bjorn Andersson @ 2017-10-12 3:56 UTC (permalink / raw)
To: Chris Lew
Cc: andy.gross, david.brown, aneela, linux-arm-msm, linux-soc,
linux-kernel, clew
On Wed 11 Oct 14:29 PDT 2017, Chris Lew wrote:
> From: Chris Lew <clew@codeaurora.org>
>
> The SMEM header structure includes the version information. Read the
> version directly from the header instead of getting an item from the
> global heap.
>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> Signed-off-by: Chris Lew <clew@codeaurora.org>
> ---
>
> Changes since v1:
> - Remove unused smem item version macro
> - Move smem get version change to separate commit
>
> Changes since v2:
> - Reduce subject to 50 chars and wrap summary to 72 chars
>
> drivers/soc/qcom/smem.c | 25 ++++++++-----------------
> 1 file changed, 8 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> index db04c45d4132..540322ae409e 100644
> --- a/drivers/soc/qcom/smem.c
> +++ b/drivers/soc/qcom/smem.c
> @@ -63,13 +63,12 @@
> */
>
> /*
> - * Item 3 of the global heap contains an array of versions for the various
> - * software components in the SoC. We verify that the boot loader version is
> - * what the expected version (SMEM_EXPECTED_VERSION) as a sanity check.
> + * The version member of the smem header contains an array of versions for the
> + * various software components in the SoC. We verify that the boot loader
> + * version is a valid version as a sanity check.
> */
> -#define SMEM_ITEM_VERSION 3
> -#define SMEM_MASTER_SBL_VERSION_INDEX 7
> -#define SMEM_EXPECTED_VERSION 11
> +#define SMEM_MASTER_SBL_VERSION_INDEX 7
> +#define SMEM_EXPECTED_VERSION 11
>
> /*
> * The first 8 items are only to be allocated by the boot loader while
> @@ -604,19 +603,11 @@ int qcom_smem_get_free_space(unsigned host)
>
> static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
> {
> + struct smem_header *header;
> __le32 *versions;
> - size_t size;
> -
> - versions = qcom_smem_get_global(smem, SMEM_ITEM_VERSION, &size);
> - if (IS_ERR(versions)) {
> - dev_err(smem->dev, "Unable to read the version item\n");
> - return -ENOENT;
> - }
>
> - if (size < sizeof(unsigned) * SMEM_MASTER_SBL_VERSION_INDEX) {
> - dev_err(smem->dev, "Version item is too small\n");
> - return -EINVAL;
> - }
> + header = smem->regions[0].virt_base;
> + versions = header->version;
>
> return le32_to_cpu(versions[SMEM_MASTER_SBL_VERSION_INDEX]);
> }
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 3/5] soc: qcom: smem: Support global partition
2017-10-11 21:29 ` [PATCH v3 3/5] soc: qcom: smem: Support global partition Chris Lew
@ 2017-10-12 3:57 ` Bjorn Andersson
0 siblings, 0 replies; 11+ messages in thread
From: Bjorn Andersson @ 2017-10-12 3:57 UTC (permalink / raw)
To: Chris Lew
Cc: andy.gross, david.brown, aneela, linux-arm-msm, linux-soc,
linux-kernel, clew
On Wed 11 Oct 14:29 PDT 2017, Chris Lew wrote:
> From: Chris Lew <clew@codeaurora.org>
>
> SMEM V12 creates a global partition to allocate global smem items from
> instead of a global heap. The global partition has the same structure as
> a private partition.
>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> Signed-off-by: Chris Lew <clew@codeaurora.org>
> ---
>
> Changes since v1:
> - Move V12 descriptions to top comment
> - Add cacheline support to global partition
> - Add ptable get helper function
> - Move global partition init to version check
>
> Changes since v2:
> - Return -ENOENT if partition table does not exist
> - Exclude -ENOENT error propagation from enumerate_partitions()
> - Reduce subject to 50 chars and wrap summary to 72 chars
>
> drivers/soc/qcom/smem.c | 172 +++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 142 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> index 540322ae409e..6a3134e9c591 100644
> --- a/drivers/soc/qcom/smem.c
> +++ b/drivers/soc/qcom/smem.c
> @@ -55,6 +55,10 @@
> * is hence the region between the cached and non-cached offsets. The header of
> * cached items comes after the data.
> *
> + * Version 12 (SMEM_GLOBAL_PART_VERSION) changes the item alloc/get procedure
> + * for the global heap. A new global partition is created from the global heap
> + * region with partition type (SMEM_GLOBAL_HOST) and the max smem item count is
> + * set by the bootloader.
> *
> * To synchronize allocations in the shared memory heaps a remote spinlock must
> * be held - currently lock number 3 of the sfpb or tcsr is used for this on all
> @@ -68,7 +72,8 @@
> * version is a valid version as a sanity check.
> */
> #define SMEM_MASTER_SBL_VERSION_INDEX 7
> -#define SMEM_EXPECTED_VERSION 11
> +#define SMEM_GLOBAL_HEAP_VERSION 11
> +#define SMEM_GLOBAL_PART_VERSION 12
>
> /*
> * The first 8 items are only to be allocated by the boot loader while
> @@ -82,6 +87,9 @@
> /* Processor/host identifier for the application processor */
> #define SMEM_HOST_APPS 0
>
> +/* Processor/host identifier for the global partition */
> +#define SMEM_GLOBAL_HOST 0xfffe
> +
> /* Max number of processors/hosts in a system */
> #define SMEM_HOST_COUNT 9
>
> @@ -230,6 +238,8 @@ struct smem_region {
> * struct qcom_smem - device data for the smem device
> * @dev: device pointer
> * @hwlock: reference to a hwspinlock
> + * @global_partition: pointer to global partition when in use
> + * @global_cacheline: cacheline size for global partition
> * @partitions: list of pointers to partitions affecting the current
> * processor/host
> * @cacheline: list of cacheline sizes for each host
> @@ -241,6 +251,8 @@ struct qcom_smem {
>
> struct hwspinlock *hwlock;
>
> + struct smem_partition_header *global_partition;
> + size_t global_cacheline;
> struct smem_partition_header *partitions[SMEM_HOST_COUNT];
> size_t cacheline[SMEM_HOST_COUNT];
>
> @@ -317,16 +329,14 @@ static void *cached_entry_to_item(struct smem_private_entry *e)
> #define HWSPINLOCK_TIMEOUT 1000
>
> static int qcom_smem_alloc_private(struct qcom_smem *smem,
> - unsigned host,
> + struct smem_partition_header *phdr,
> unsigned item,
> size_t size)
> {
> - struct smem_partition_header *phdr;
> struct smem_private_entry *hdr, *end;
> size_t alloc_size;
> void *cached;
>
> - phdr = smem->partitions[host];
> hdr = phdr_to_first_uncached_entry(phdr);
> end = phdr_to_last_uncached_entry(phdr);
> cached = phdr_to_last_cached_entry(phdr);
> @@ -334,8 +344,8 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
> while (hdr < end) {
> if (hdr->canary != SMEM_PRIVATE_CANARY) {
> dev_err(smem->dev,
> - "Found invalid canary in host %d partition\n",
> - host);
> + "Found invalid canary in hosts %d:%d partition\n",
> + phdr->host0, phdr->host1);
> return -EINVAL;
> }
>
> @@ -373,8 +383,8 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
> unsigned item,
> size_t size)
> {
> - struct smem_header *header;
> struct smem_global_entry *entry;
> + struct smem_header *header;
>
> if (WARN_ON(item >= SMEM_ITEM_COUNT))
> return -EINVAL;
> @@ -416,6 +426,7 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
> */
> int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
> {
> + struct smem_partition_header *phdr;
> unsigned long flags;
> int ret;
>
> @@ -434,10 +445,15 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
> if (ret)
> return ret;
>
> - if (host < SMEM_HOST_COUNT && __smem->partitions[host])
> - ret = qcom_smem_alloc_private(__smem, host, item, size);
> - else
> + if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
> + phdr = __smem->partitions[host];
> + ret = qcom_smem_alloc_private(__smem, phdr, item, size);
> + } else if (__smem->global_partition) {
> + phdr = __smem->global_partition;
> + ret = qcom_smem_alloc_private(__smem, phdr, item, size);
> + } else {
> ret = qcom_smem_alloc_global(__smem, item, size);
> + }
>
> hwspin_unlock_irqrestore(__smem->hwlock, &flags);
>
> @@ -479,16 +495,12 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
> }
>
> static void *qcom_smem_get_private(struct qcom_smem *smem,
> - unsigned host,
> + struct smem_partition_header *phdr,
> + size_t cacheline,
> unsigned item,
> size_t *size)
> {
> - struct smem_partition_header *phdr;
> struct smem_private_entry *e, *end;
> - size_t cacheline;
> -
> - phdr = smem->partitions[host];
> - cacheline = smem->cacheline[host];
>
> e = phdr_to_first_uncached_entry(phdr);
> end = phdr_to_last_uncached_entry(phdr);
> @@ -531,7 +543,8 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
> return ERR_PTR(-ENOENT);
>
> invalid_canary:
> - dev_err(smem->dev, "Found invalid canary in host %d partition\n", host);
> + dev_err(smem->dev, "Found invalid canary in hosts %d:%d partition\n",
> + phdr->host0, phdr->host1);
>
> return ERR_PTR(-EINVAL);
> }
> @@ -547,7 +560,9 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
> */
> void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
> {
> + struct smem_partition_header *phdr;
> unsigned long flags;
> + size_t cacheln;
> int ret;
> void *ptr = ERR_PTR(-EPROBE_DEFER);
>
> @@ -560,10 +575,17 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
> if (ret)
> return ERR_PTR(ret);
>
> - if (host < SMEM_HOST_COUNT && __smem->partitions[host])
> - ptr = qcom_smem_get_private(__smem, host, item, size);
> - else
> + if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
> + phdr = __smem->partitions[host];
> + cacheln = __smem->cacheline[host];
> + ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
> + } else if (__smem->global_partition) {
> + phdr = __smem->global_partition;
> + cacheln = __smem->global_cacheline;
> + ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
> + } else {
> ptr = qcom_smem_get_global(__smem, item, size);
> + }
>
> hwspin_unlock_irqrestore(__smem->hwlock, &flags);
>
> @@ -592,6 +614,10 @@ int qcom_smem_get_free_space(unsigned host)
> phdr = __smem->partitions[host];
> ret = le32_to_cpu(phdr->offset_free_cached) -
> le32_to_cpu(phdr->offset_free_uncached);
> + } else if (__smem->global_partition) {
> + phdr = __smem->global_partition;
> + ret = le32_to_cpu(phdr->offset_free_cached) -
> + le32_to_cpu(phdr->offset_free_uncached);
> } else {
> header = __smem->regions[0].virt_base;
> ret = le32_to_cpu(header->available);
> @@ -612,27 +638,106 @@ static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
> return le32_to_cpu(versions[SMEM_MASTER_SBL_VERSION_INDEX]);
> }
>
> -static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
> - unsigned local_host)
> +static struct smem_ptable *qcom_smem_get_ptable(struct qcom_smem *smem)
> {
> - struct smem_partition_header *header;
> - struct smem_ptable_entry *entry;
> struct smem_ptable *ptable;
> - unsigned remote_host;
> - u32 version, host0, host1;
> - int i;
> + u32 version;
>
> ptable = smem->regions[0].virt_base + smem->regions[0].size - SZ_4K;
> if (memcmp(ptable->magic, SMEM_PTABLE_MAGIC, sizeof(ptable->magic)))
> - return 0;
> + return ERR_PTR(-ENOENT);
>
> version = le32_to_cpu(ptable->version);
> if (version != 1) {
> dev_err(smem->dev,
> "Unsupported partition header version %d\n", version);
> + return ERR_PTR(-EINVAL);
> + }
> + return ptable;
> +}
> +
> +static int qcom_smem_set_global_partition(struct qcom_smem *smem)
> +{
> + struct smem_partition_header *header;
> + struct smem_ptable_entry *entry = NULL;
> + struct smem_ptable *ptable;
> + u32 host0, host1, size;
> + int i;
> +
> + ptable = qcom_smem_get_ptable(smem);
> + if (IS_ERR(ptable))
> + return PTR_ERR(ptable);
> +
> + for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
> + entry = &ptable->entry[i];
> + host0 = le16_to_cpu(entry->host0);
> + host1 = le16_to_cpu(entry->host1);
> +
> + if (host0 == SMEM_GLOBAL_HOST && host0 == host1)
> + break;
> + }
> +
> + if (!entry) {
> + dev_err(smem->dev, "Missing entry for global partition\n");
> + return -EINVAL;
> + }
> +
> + if (!le32_to_cpu(entry->offset) || !le32_to_cpu(entry->size)) {
> + dev_err(smem->dev, "Invalid entry for global partition\n");
> + return -EINVAL;
> + }
> +
> + if (smem->global_partition) {
> + dev_err(smem->dev, "Already found the global partition\n");
> + return -EINVAL;
> + }
> +
> + header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
> + host0 = le16_to_cpu(header->host0);
> + host1 = le16_to_cpu(header->host1);
> +
> + if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
> + dev_err(smem->dev, "Global partition has invalid magic\n");
> + return -EINVAL;
> + }
> +
> + if (host0 != SMEM_GLOBAL_HOST && host1 != SMEM_GLOBAL_HOST) {
> + dev_err(smem->dev, "Global partition hosts are invalid\n");
> + return -EINVAL;
> + }
> +
> + if (le32_to_cpu(header->size) != le32_to_cpu(entry->size)) {
> + dev_err(smem->dev, "Global partition has invalid size\n");
> return -EINVAL;
> }
>
> + size = le32_to_cpu(header->offset_free_uncached);
> + if (size > le32_to_cpu(header->size)) {
> + dev_err(smem->dev,
> + "Global partition has invalid free pointer\n");
> + return -EINVAL;
> + }
> +
> + smem->global_partition = header;
> + smem->global_cacheline = le32_to_cpu(entry->cacheline);
> +
> + return 0;
> +}
> +
> +static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
> + unsigned int local_host)
> +{
> + struct smem_partition_header *header;
> + struct smem_ptable_entry *entry;
> + struct smem_ptable *ptable;
> + unsigned int remote_host;
> + u32 host0, host1;
> + int i;
> +
> + ptable = qcom_smem_get_ptable(smem);
> + if (IS_ERR(ptable))
> + return PTR_ERR(ptable);
> +
> for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
> entry = &ptable->entry[i];
> host0 = le16_to_cpu(entry->host0);
> @@ -773,13 +878,20 @@ static int qcom_smem_probe(struct platform_device *pdev)
> }
>
> version = qcom_smem_get_sbl_version(smem);
> - if (version >> 16 != SMEM_EXPECTED_VERSION) {
> + switch (version >> 16) {
> + case SMEM_GLOBAL_PART_VERSION:
> + ret = qcom_smem_set_global_partition(smem);
> + if (ret < 0)
> + return ret;
> + case SMEM_GLOBAL_HEAP_VERSION:
> + break;
> + default:
> dev_err(&pdev->dev, "Unsupported SMEM version 0x%x\n", version);
> return -EINVAL;
> }
>
> ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS);
> - if (ret < 0)
> + if (ret < 0 && ret != -ENOENT)
> return ret;
>
> hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0);
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 4/5] soc: qcom: smem: Support dynamic item limit
2017-10-11 21:29 ` [PATCH v3 4/5] soc: qcom: smem: Support dynamic item limit Chris Lew
@ 2017-10-12 3:58 ` Bjorn Andersson
0 siblings, 0 replies; 11+ messages in thread
From: Bjorn Andersson @ 2017-10-12 3:58 UTC (permalink / raw)
To: Chris Lew
Cc: andy.gross, david.brown, aneela, linux-arm-msm, linux-soc,
linux-kernel, clew
On Wed 11 Oct 14:29 PDT 2017, Chris Lew wrote:
> From: Chris Lew <clew@codeaurora.org>
>
> In V12 SMEM, SBL writes SMEM parameter information after the TOC. Use
> the SBL provided item count as the max item number.
>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> Signed-off-by: Chris Lew <clew@codeaurora.org>
> ---
>
> Changes since v1:
> - Change num_items to __le16 from __le32
> - Move max smem item warning to generic get/alloc functions
> - Use get ptable helper function
>
> Changes since v2:
> - Rename qcom_smem_get_dynamic_item to qcom_smem_get_item_count
> - Reduce subject to 50 chars and wrap summary to 72 chars
>
> drivers/soc/qcom/smem.c | 51 +++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 45 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> index 6a3134e9c591..19704baa65f4 100644
> --- a/drivers/soc/qcom/smem.c
> +++ b/drivers/soc/qcom/smem.c
> @@ -223,6 +223,24 @@ struct smem_private_entry {
> #define SMEM_PRIVATE_CANARY 0xa5a5
>
> /**
> + * struct smem_info - smem region info located after the table of contents
> + * @magic: magic number, must be SMEM_INFO_MAGIC
> + * @size: size of the smem region
> + * @base_addr: base address of the smem region
> + * @reserved: for now reserved entry
> + * @num_items: highest accepted item number
> + */
> +struct smem_info {
> + u8 magic[4];
> + __le32 size;
> + __le32 base_addr;
> + __le32 reserved;
> + __le16 num_items;
> +};
> +
> +static const u8 SMEM_INFO_MAGIC[] = { 0x53, 0x49, 0x49, 0x49 }; /* SIII */
> +
> +/**
> * struct smem_region - representation of a chunk of memory used for smem
> * @aux_base: identifier of aux_mem base
> * @virt_base: virtual base address of memory with this aux_mem identifier
> @@ -243,6 +261,7 @@ struct smem_region {
> * @partitions: list of pointers to partitions affecting the current
> * processor/host
> * @cacheline: list of cacheline sizes for each host
> + * @item_count: max accepted item number
> * @num_regions: number of @regions
> * @regions: list of the memory regions defining the shared memory
> */
> @@ -255,6 +274,7 @@ struct qcom_smem {
> size_t global_cacheline;
> struct smem_partition_header *partitions[SMEM_HOST_COUNT];
> size_t cacheline[SMEM_HOST_COUNT];
> + u32 item_count;
>
> unsigned num_regions;
> struct smem_region regions[0];
> @@ -386,9 +406,6 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
> struct smem_global_entry *entry;
> struct smem_header *header;
>
> - if (WARN_ON(item >= SMEM_ITEM_COUNT))
> - return -EINVAL;
> -
> header = smem->regions[0].virt_base;
> entry = &header->toc[item];
> if (entry->allocated)
> @@ -439,6 +456,9 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
> return -EINVAL;
> }
>
> + if (WARN_ON(item >= __smem->item_count))
> + return -EINVAL;
> +
> ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
> HWSPINLOCK_TIMEOUT,
> &flags);
> @@ -471,9 +491,6 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
> u32 aux_base;
> unsigned i;
>
> - if (WARN_ON(item >= SMEM_ITEM_COUNT))
> - return ERR_PTR(-EINVAL);
> -
> header = smem->regions[0].virt_base;
> entry = &header->toc[item];
> if (!entry->allocated)
> @@ -569,6 +586,9 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
> if (!__smem)
> return ptr;
>
> + if (WARN_ON(item >= __smem->item_count))
> + return ERR_PTR(-EINVAL);
> +
> ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
> HWSPINLOCK_TIMEOUT,
> &flags);
> @@ -656,6 +676,22 @@ static struct smem_ptable *qcom_smem_get_ptable(struct qcom_smem *smem)
> return ptable;
> }
>
> +static u32 qcom_smem_get_item_count(struct qcom_smem *smem)
> +{
> + struct smem_ptable *ptable;
> + struct smem_info *info;
> +
> + ptable = qcom_smem_get_ptable(smem);
> + if (IS_ERR_OR_NULL(ptable))
> + return SMEM_ITEM_COUNT;
> +
> + info = (struct smem_info *)&ptable->entry[ptable->num_entries];
> + if (memcmp(info->magic, SMEM_INFO_MAGIC, sizeof(info->magic)))
> + return SMEM_ITEM_COUNT;
> +
> + return le16_to_cpu(info->num_items);
> +}
> +
> static int qcom_smem_set_global_partition(struct qcom_smem *smem)
> {
> struct smem_partition_header *header;
> @@ -883,7 +919,10 @@ static int qcom_smem_probe(struct platform_device *pdev)
> ret = qcom_smem_set_global_partition(smem);
> if (ret < 0)
> return ret;
> + smem->item_count = qcom_smem_get_item_count(smem);
> + break;
> case SMEM_GLOBAL_HEAP_VERSION:
> + smem->item_count = SMEM_ITEM_COUNT;
> break;
> default:
> dev_err(&pdev->dev, "Unsupported SMEM version 0x%x\n", version);
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v3 5/5] soc: qcom: smem: Increase the number of hosts
2017-10-11 21:29 ` [PATCH v3 5/5] soc: qcom: smem: Increase the number of hosts Chris Lew
@ 2017-10-12 3:59 ` Bjorn Andersson
0 siblings, 0 replies; 11+ messages in thread
From: Bjorn Andersson @ 2017-10-12 3:59 UTC (permalink / raw)
To: Chris Lew
Cc: andy.gross, david.brown, aneela, linux-arm-msm, linux-soc,
linux-kernel, clew
On Wed 11 Oct 14:29 PDT 2017, Chris Lew wrote:
> From: Chris Lew <clew@codeaurora.org>
>
> Increase the maximum number of hosts in a system to 10.
>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> Signed-off-by: Chris Lew <clew@codeaurora.org>
> ---
>
> Changes since v1:
> - None
>
> Changes since v2:
> - None
>
> drivers/soc/qcom/smem.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> index 19704baa65f4..0b94d62fad2b 100644
> --- a/drivers/soc/qcom/smem.c
> +++ b/drivers/soc/qcom/smem.c
> @@ -91,7 +91,7 @@
> #define SMEM_GLOBAL_HOST 0xfffe
>
> /* Max number of processors/hosts in a system */
> -#define SMEM_HOST_COUNT 9
> +#define SMEM_HOST_COUNT 10
>
> /**
> * struct smem_proc_comm - proc_comm communication struct (legacy)
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2017-10-12 3:59 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-11 21:29 [PATCH v3 0/5] Qualcomm SMEM V12 Support Chris Lew
2017-10-11 21:29 ` [PATCH v3 1/5] soc: qcom: smem: Use le32_to_cpu for comparison Chris Lew
2017-10-12 3:54 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 2/5] soc: qcom: smem: Read version from the smem header Chris Lew
2017-10-12 3:56 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 3/5] soc: qcom: smem: Support global partition Chris Lew
2017-10-12 3:57 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 4/5] soc: qcom: smem: Support dynamic item limit Chris Lew
2017-10-12 3:58 ` Bjorn Andersson
2017-10-11 21:29 ` [PATCH v3 5/5] soc: qcom: smem: Increase the number of hosts Chris Lew
2017-10-12 3:59 ` Bjorn Andersson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.