1 /* 2 * (C) Copyright 2022 Rockchip Electronics Co., Ltd. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 /* 8 * Example: 9 * ramoops: ramoops@110000 { 10 * compatible = "ramoops"; 11 * reg = <0x0 0x110000 0x0 0xe0000>; 12 * boot-log-size = <0x8000>; 13 * boot-log-count = <0x1> 14 * console-size = <0x80000>; 15 * pmsg-size = <0x30000>; 16 * ftrace-size = <0x00000>; 17 * record-size = <0x14000>; 18 * }; 19 */ 20 21 #include <common.h> 22 #include <asm/arch/rk_atags.h> 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 #define PERSISTENT_RAM_SIG (0x43474244) 27 #define LOG_TYPE_MASK (0x00000fff) 28 29 struct persistent_ram_buffer { 30 u32 sig; 31 u32 start; 32 u32 size; 33 u8 data[0]; 34 }; 35 36 enum log_type { 37 LOG_TPL = 0, 38 LOG_SPL, 39 LOG_OPTEE, 40 LOG_ATF, 41 LOG_UBOOT, 42 LOG_MAX = 12, 43 }; 44 45 #if 0 46 /* 47 * This function is to be called by tpl/ddr. 48 * 49 * u32 'conf' definition: 50 * [31:16] is pstore buffer base address (0x_[31:16]_0000), 64KB align. 51 * [15:12] is pstore buffer size [15:12]*4KB. 52 * [11:0] see 'enum log_type' per bit is for one stage, 1: enable, 0: disable. 53 * [0] tpl(ddr) 54 * [1] spl(miniloader) 55 * [2] optee(bl32) 56 * [3] atf(bl31) 57 * [4] U-Boot 58 * ... 59 */ 60 void pstore_atags_set_tag(u32 conf) 61 { 62 struct tag_pstore t; 63 u32 addr = conf & 0xffff0000; 64 u32 size = conf & 0x0000f000; 65 int i = 0; 66 67 /* handle special: 0 is 64KB but not 0KB */ 68 if (size == 0) 69 size = 0x10000; 70 71 /* is enabled log type ? */ 72 conf &= LOG_TYPE_MASK; 73 if (conf == 0) 74 return; 75 76 t.version = 0; 77 for (i = 0; i < LOG_MAX; i++) { 78 if (conf & (1 << (i))) { 79 t.buf[i].addr = addr; 80 t.buf[i].size = size; 81 } else { 82 t.buf[i].addr = 0x0; 83 t.buf[i].size = 0x0; 84 } 85 } 86 87 atags_set_tag(ATAG_PSTORE, &t); 88 } 89 #endif 90 91 int param_parse_pstore(void) 92 { 93 struct persistent_ram_buffer *rb = NULL; 94 u32 pstore_size = 0; 95 #if defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS) && (CONFIG_PERSISTENT_RAM_ADDR == 0) 96 struct tag *t; 97 98 gd->pstore_addr = 0; 99 gd->pstore_size = 0; 100 101 t = atags_get_tag(ATAG_PSTORE); 102 if (t) { 103 gd->pstore_addr = t->u.pstore.buf[LOG_UBOOT].addr; 104 gd->pstore_size = t->u.pstore.buf[LOG_UBOOT].size - sizeof(struct persistent_ram_buffer); 105 } 106 #elif (CONFIG_PERSISTENT_RAM_ADDR == 0 || CONFIG_PERSISTENT_RAM_SIZE == 0) 107 #error: CONFIG_PERSISTENT_RAM_SIZE and CONFIG_PERSISTENT_RAM_ADDR value should not be 0. 108 #else 109 gd->pstore_addr = CONFIG_PERSISTENT_RAM_ADDR; 110 gd->pstore_size = CONFIG_PERSISTENT_RAM_SIZE - sizeof(struct persistent_ram_buffer); 111 #endif 112 if (gd->pstore_addr) { 113 rb = (struct persistent_ram_buffer *)gd->pstore_addr; 114 pstore_size = gd->pstore_size; 115 116 if (rb->sig != PERSISTENT_RAM_SIG) { 117 rb->sig = PERSISTENT_RAM_SIG; 118 rb->start = 0x0; 119 rb->size = 0x0; 120 } 121 122 if (rb->size > pstore_size) 123 rb->size = pstore_size; 124 125 if (rb->start >= pstore_size) 126 rb->start = 0; 127 } 128 129 return 0; 130 } 131 132 void putc_to_ram(const char c) 133 { 134 struct persistent_ram_buffer *rb = (struct persistent_ram_buffer *)gd->pstore_addr; 135 u32 pstore_size = gd->pstore_size; 136 u8 *dst; 137 138 if (!rb || pstore_size == 0) 139 return; 140 141 if (rb->start >= pstore_size) 142 rb->start = 0; 143 144 dst = rb->data + rb->start; 145 *dst = c; 146 147 if (rb->size < pstore_size) 148 rb->size++; 149 else 150 rb->size = pstore_size; 151 152 rb->start++; 153 } 154 155 void puts_to_ram(const char *str) 156 { 157 while (*str) { 158 putc_to_ram(*str++); 159 } 160 } 161