Skip to content

Commit bfdf95c

Browse files
jiegan0107shashim-quic
authored andcommitted
QCLINUX: memory-dump: add logic for reserving CMA memory
Memory dump driver needs a large CMA memory zone for storing memory dump table. Add codes for reserving CMA memory during the init stage. Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
1 parent 202126a commit bfdf95c

5 files changed

Lines changed: 31 additions & 38 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
CONFIG_QCOM_DCC=m
22
CONFIG_QCOM_DCC_DEV=m
3-
CONFIG_QCOM_MEMORY_DUMP_V2=m
3+
CONFIG_QCOM_MEMORY_DUMP_V2=y
44
CONFIG_QCOM_MEMORY_DUMP_DEV=m

arch/arm64/mm/init.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <asm/tlb.h>
4949
#include <asm/alternative.h>
5050
#include <asm/xen/swiotlb-xen.h>
51+
#include <linux/firmware/qcom/memory_dump.h>
5152

5253
/*
5354
* We need to be able to catch inadvertent references to memstart_addr
@@ -331,6 +332,9 @@ void __init bootmem_init(void)
331332
* reserved, so do it here.
332333
*/
333334
arch_reserve_crashkernel();
335+
#if defined(CONFIG_QCOM_MEMORY_DUMP_V2)
336+
reserve_memdump_cma();
337+
#endif
334338

335339
memblock_dump_all();
336340
}

drivers/firmware/qcom/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ config QCOM_QSEECOM_UEFISECAPP
7777
config QCOM_MEMORY_DUMP_V2
7878
tristate "QCOM Memory Dump V2 Support"
7979
depends on QCOM_TZMEM
80+
depends on CMA
8081
help
8182
This enables memory dump feature. It allows various client
8283
subsystems to register respective dump regions. At the time

drivers/firmware/qcom/memory_dump_v2.c

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include <linux/platform_device.h>
1919
#include <linux/firmware/qcom/qcom_tzmem.h>
2020
#include <linux/firmware/qcom/memory_dump.h>
21+
#include <linux/cma.h>
22+
#include <linux/vmalloc.h>
23+
#include <linux/mm.h>
24+
#include <linux/dma-map-ops.h>
2125

2226
#define MSM_DUMP_TABLE_VERSION MSM_DUMP_MAKE_VERSION(2, 0)
2327

@@ -913,30 +917,6 @@ static int init_memory_dump(void *dump_vaddr, phys_addr_t phys_addr)
913917
return 0;
914918
}
915919

916-
static int mem_dump_reserve_mem(struct device *dev)
917-
{
918-
struct device_node *mem_node;
919-
struct reserved_mem *rmem;
920-
int ret;
921-
922-
mem_node = of_find_node_by_path("/reserved-memory/mem-dump-region");
923-
if (mem_node) {
924-
rmem = of_reserved_mem_lookup(mem_node);
925-
of_node_put(mem_node);
926-
if (!rmem || !rmem->ops || !rmem->ops->device_init)
927-
return -EINVAL;
928-
929-
ret = rmem->ops->device_init(rmem, dev);
930-
if (ret) {
931-
dev_err(dev,
932-
"Failed to initialize reserved mem, ret %d\n",
933-
ret);
934-
return ret;
935-
}
936-
}
937-
return 0;
938-
}
939-
940920
static int cpuss_regdump_init(struct device *dev,
941921
void *dump_vaddr, u32 size)
942922
{
@@ -998,6 +978,18 @@ static int cpuss_dump_init(struct platform_device *pdev,
998978
return initialized;
999979
}
1000980

981+
struct cma *memdump_cma;
982+
void __init reserve_memdump_cma(void)
983+
{
984+
unsigned long long cma_size = 0x3000000;
985+
unsigned long long request_size = roundup(cma_size, PAGE_SIZE);
986+
987+
if (cma_declare_contiguous(0, request_size, 0, 0, 0, false,
988+
"memdump", &memdump_cma)) {
989+
pr_warn("memdump CMA reservation failed\n");
990+
}
991+
}
992+
1001993
#define MSM_DUMP_DATA_SIZE sizeof(struct msm_dump_data)
1002994
static int mem_dump_alloc(struct platform_device *pdev)
1003995
{
@@ -1006,16 +998,13 @@ static int mem_dump_alloc(struct platform_device *pdev)
1006998
size_t total_size;
1007999
u32 size, id;
10081000
int i, ret, no_of_nodes;
1009-
dma_addr_t dma_handle;
10101001
phys_addr_t phys_addr;
1011-
struct sg_table mem_dump_sgt;
10121002
void *dump_vaddr;
10131003
u64 shm_bridge_handle;
10141004
int initialized = 0;
10151005
const struct dump_table *table = dev_get_platdata(&pdev->dev);
1006+
struct page *reserved_page;
10161007

1017-
if (mem_dump_reserve_mem(&pdev->dev) != 0)
1018-
return -ENOMEM;
10191008
total_size = size = ret = no_of_nodes = 0;
10201009
/* For dump table registration with IMEM */
10211010
total_size = sizeof(struct msm_dump_table) * 2;
@@ -1026,15 +1015,12 @@ static int mem_dump_alloc(struct platform_device *pdev)
10261015

10271016
total_size += (MSM_DUMP_DATA_SIZE * no_of_nodes);
10281017
total_size = ALIGN(total_size, SZ_4K);
1029-
dump_vaddr = dmam_alloc_coherent(&pdev->dev, total_size,
1030-
&dma_handle, GFP_KERNEL);
1031-
if (!dump_vaddr)
1018+
reserved_page = cma_alloc(memdump_cma, total_size >> PAGE_SHIFT,
1019+
0, false);
1020+
if (!reserved_page)
10321021
return -ENOMEM;
1033-
1034-
dma_get_sgtable(&pdev->dev, &mem_dump_sgt, dump_vaddr,
1035-
dma_handle, total_size);
1036-
phys_addr = page_to_phys(sg_page(mem_dump_sgt.sgl));
1037-
sg_free_table(&mem_dump_sgt);
1022+
phys_addr = page_to_phys(reserved_page);
1023+
dump_vaddr = page_to_virt(reserved_page);
10381024

10391025
memset(dump_vaddr, 0x0, total_size);
10401026
ret = qcom_tzmem_shm_bridge_create(phys_addr, total_size, &shm_bridge_handle);

include/linux/firmware/qcom/memory_dump.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ struct msm_client_dump {
3333
unsigned long end_addr;
3434
};
3535

36+
void __init reserve_memdump_cma(void);
37+
extern struct cma *memdump_cma;
38+
3639
#ifdef CONFIG_QCOM_MEMORY_DUMP
3740
extern int msm_dump_tbl_register(struct msm_client_dump *client_entry);
3841
#else
@@ -42,7 +45,6 @@ static inline int msm_dump_tbl_register(struct msm_client_dump *entry)
4245
}
4346
#endif
4447

45-
4648
#if IS_ENABLED(CONFIG_QCOM_MEMORY_DUMP_V2)
4749
extern uint32_t msm_dump_table_version(void);
4850
#else

0 commit comments

Comments
 (0)