blob: 6ff1e2b713c580a9416019dd33b1872663eb8ded [file] [log] [blame]
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -06001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include "psp_verstage.h"
4
5#include <bl_uapp/bl_errorcodes_public.h>
6#include <bl_uapp/bl_syscall_public.h>
7#include <boot_device.h>
8#include <commonlib/region.h>
9#include <console/console.h>
10#include <string.h>
11
12#define DEST_BUF_ALIGNMENT 16
13
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060014static uint32_t active_map_count;
15
16static void *boot_dev_mmap(const struct region_device *rd, size_t offset, size_t size)
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060017{
18 const struct mem_region_device *mdev;
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060019 void *mapping = NULL;
20 uint32_t ret;
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060021
22 mdev = container_of(rd, __typeof__(*mdev), rdev);
Karthikeyan Ramasubramanianb6ab7ba2023-11-20 23:34:22 +000023 if (CONFIG(PSP_VERSTAGE_MAP_ENTIRE_SPIROM))
24 return &(mdev->base[offset]);
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060025
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060026 if (mdev->base) {
27 if ((ret = svc_map_spi_rom(&mdev->base[offset], size, (void **)&mapping))
28 != BL_OK)
29 printk(BIOS_ERR, "Failed(%d) to map SPI ROM offset: %zu, size: %zu\n",
30 ret, offset, size);
31 else
32 active_map_count++;
33 }
34
35 return mapping;
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060036}
37
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060038static int boot_dev_munmap(const struct region_device *rd, void *mapping)
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060039{
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060040 uint32_t ret;
41
Karthikeyan Ramasubramanianb6ab7ba2023-11-20 23:34:22 +000042 if (CONFIG(PSP_VERSTAGE_MAP_ENTIRE_SPIROM))
43 return 0;
44
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060045 active_map_count--;
46 if ((ret = svc_unmap_spi_rom(mapping)) != BL_OK)
47 printk(BIOS_ERR, "Failed(%d) to unmap SPI ROM mapping %p\n", ret, mapping);
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060048 return 0;
49}
50
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060051static ssize_t boot_dev_mmap_readat(const struct region_device *rd, void *dest,
52 size_t offset, size_t size)
53{
54 void *mapping = boot_dev_mmap(rd, offset, size);
55
56 if (!mapping)
57 return -1;
58
59 memcpy(dest, mapping, size);
60 boot_dev_munmap(rd, mapping);
61 return size;
62}
63
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060064static ssize_t boot_dev_dma_readat(const struct region_device *rd, void *dest,
65 size_t offset, size_t size)
66{
67 size_t memcpy_size = ALIGN_UP((uintptr_t)dest, DEST_BUF_ALIGNMENT) - (uintptr_t)dest;
68 const struct mem_region_device *mdev = container_of(rd, __typeof__(*mdev), rdev);
69 int ret;
70
71 if (memcpy_size > size)
72 memcpy_size = size;
73 /* Alignment requirement is only on dest buffer for CCP DMA. So do a memcpy
74 until the destination buffer alignment requirement is met. */
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -060075 if (memcpy_size && boot_dev_mmap_readat(rd, dest, offset, memcpy_size) != memcpy_size)
76 return -1;
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -060077
78 dest = ((char *)dest + memcpy_size);
79 offset += memcpy_size;
80 size -= memcpy_size;
81 if (!size)
82 return memcpy_size;
83
84 ret = svc_ccp_dma((uint32_t)offset, dest, (uint32_t)size);
85 if (ret != BL_OK) {
86 printk(BIOS_ERR, "%s: Failed dest:%p offset:%zu size:%zu ret:%d\n",
87 __func__, dest, offset, size, ret);
88 return -1;
89 }
90
91 return size + memcpy_size;
92}
93
94static ssize_t boot_dev_readat(const struct region_device *rd, void *dest,
95 size_t offset, size_t size)
96{
97 const struct mem_region_device *mdev = container_of(rd, __typeof__(*mdev), rdev);
98
99 if (CONFIG(PSP_VERSTAGE_CCP_DMA))
100 return boot_dev_dma_readat(rd, dest, offset, size);
101
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -0600102 return boot_dev_mmap_readat(rd, dest, offset, size);
Karthikeyan Ramasubramanianc2f6f352021-09-10 12:03:30 -0600103}
104
105const struct region_device_ops boot_dev_rdev_ro_ops = {
106 .mmap = boot_dev_mmap,
107 .munmap = boot_dev_munmap,
108 .readat = boot_dev_readat,
109};
110
111static struct mem_region_device boot_dev = {
112 .rdev = REGION_DEV_INIT(&boot_dev_rdev_ro_ops, 0, CONFIG_ROM_SIZE),
113};
114
115const struct region_device *boot_device_ro(void)
116{
117 if (!boot_dev.base)
118 boot_dev.base = (void *)map_spi_rom();
119 return &boot_dev.rdev;
120}
Karthikeyan Ramasubramanian6f1b03b2023-04-21 14:26:51 -0600121
122uint32_t boot_dev_get_active_map_count(void)
123{
124 return active_map_count;
125}