1 // SPDX-License-Identifier: GPL-2.0-only 2 /** 3 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> 4 * Copyright (c) 2003-2004 Joern Engel <joern@wh.fh-wedel.de> 5 * 6 * Usage: 7 * 8 * one commend line parameter per device, each in the form: 9 * phram=<name>,<start>,<len> 10 * <name> may be up to 63 characters. 11 * <start> and <len> can be octal, decimal or hexadecimal. If followed 12 * by "ki", "Mi" or "Gi", the numbers will be interpreted as kilo, mega or 13 * gigabytes. 14 * 15 * Example: 16 * phram=swap,64Mi,128Mi phram=test,900Mi,1Mi 17 */ 18 19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20 21 #include <linux/io.h> 22 #include <linux/init.h> 23 #include <linux/kernel.h> 24 #include <linux/list.h> 25 #include <linux/module.h> 26 #include <linux/moduleparam.h> 27 #include <linux/slab.h> 28 #include <linux/mtd/mtd.h> 29 30 struct phram_mtd_list { 31 struct mtd_info mtd; 32 struct list_head list; 33 }; 34 35 static LIST_HEAD(phram_list); 36 37 static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) 38 { 39 u_char *start = mtd->priv; 40 41 memset(start + instr->addr, 0xff, instr->len); 42 43 return 0; 44 } 45 46 static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, 47 size_t *retlen, void **virt, resource_size_t *phys) 48 { 49 *virt = mtd->priv + from; 50 *retlen = len; 51 return 0; 52 } 53 54 static int phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) 55 { 56 return 0; 57 } 58 59 static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, 60 size_t *retlen, u_char *buf) 61 { 62 u_char *start = mtd->priv; 63 64 memcpy(buf, start + from, len); 65 *retlen = len; 66 return 0; 67 } 68 69 static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, 70 size_t *retlen, const u_char *buf) 71 { 72 u_char *start = mtd->priv; 73 74 memcpy(start + to, buf, len); 75 *retlen = len; 76 return 0; 77 } 78 79 static void unregister_devices(void) 80 { 81 struct phram_mtd_list *this, *safe; 82 83 list_for_each_entry_safe(this, safe, &phram_list, list) { 84 mtd_device_unregister(&this->mtd); 85 iounmap(this->mtd.priv); 86 kfree(this->mtd.name); 87 kfree(this); 88 } 89 } 90 91 static int register_device(char *name, phys_addr_t start, size_t len) 92 { 93 struct phram_mtd_list *new; 94 int ret = -ENOMEM; 95 96 new = kzalloc(sizeof(*new), GFP_KERNEL); 97 if (!new) 98 goto out0; 99 100 ret = -EIO; 101 new->mtd.priv = ioremap(start, len); 102 if (!new->mtd.priv) { 103 pr_err("ioremap failed\n"); 104 goto out1; 105 } 106 107 108 new->mtd.name = name; 109 new->mtd.size = len; 110 new->mtd.flags = MTD_CAP_RAM; 111 new->mtd._erase = phram_erase; 112 new->mtd._point = phram_point; 113 new->mtd._unpoint = phram_unpoint; 114 new->mtd._read = phram_read; 115 new->mtd._write = phram_write; 116 new->mtd.owner = THIS_MODULE; 117 new->mtd.type = MTD_RAM; 118 new->mtd.erasesize = PAGE_SIZE; 119 new->mtd.writesize = 1; 120 121 ret = -EAGAIN; 122 if (mtd_device_register(&new->mtd, NULL, 0)) { 123 pr_err("Failed to register new device\n"); 124 goto out2; 125 } 126 127 list_add_tail(&new->list, &phram_list); 128 return 0; 129 130 out2: 131 iounmap(new->mtd.priv); 132 out1: 133 kfree(new); 134 out0: 135 return ret; 136 } 137 138 static int parse_num64(uint64_t *num64, char *token) 139 { 140 size_t len; 141 int shift = 0; 142 int ret; 143 144 len = strlen(token); 145 /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */ 146 if (len > 2) { 147 if (token[len - 1] == 'i') { 148 switch (token[len - 2]) { 149 case 'G': 150 shift += 10; 151 fallthrough; 152 case 'M': 153 shift += 10; 154 fallthrough; 155 case 'k': 156 shift += 10; 157 token[len - 2] = 0; 158 break; 159 default: 160 return -EINVAL; 161 } 162 } 163 } 164 165 ret = kstrtou64(token, 0, num64); 166 *num64 <<= shift; 167 168 return ret; 169 } 170 171 static int parse_name(char **pname, const char *token) 172 { 173 size_t len; 174 char *name; 175 176 len = strlen(token) + 1; 177 if (len > 64) 178 return -ENOSPC; 179 180 name = kstrdup(token, GFP_KERNEL); 181 if (!name) 182 return -ENOMEM; 183 184 *pname = name; 185 return 0; 186 } 187 188 189 static inline void kill_final_newline(char *str) 190 { 191 char *newline = strrchr(str, '\n'); 192 193 if (newline && !newline[1]) 194 *newline = 0; 195 } 196 197 198 #define parse_err(fmt, args...) do { \ 199 pr_err(fmt , ## args); \ 200 return 1; \ 201 } while (0) 202 203 #ifndef MODULE 204 static int phram_init_called; 205 /* 206 * This shall contain the module parameter if any. It is of the form: 207 * - phram=<device>,<address>,<size> for module case 208 * - phram.phram=<device>,<address>,<size> for built-in case 209 * We leave 64 bytes for the device name, 20 for the address and 20 for the 210 * size. 211 * Example: phram.phram=rootfs,0xa0000000,512Mi 212 */ 213 static char phram_paramline[64 + 20 + 20]; 214 #endif 215 216 static int phram_setup(const char *val) 217 { 218 char buf[64 + 20 + 20], *str = buf; 219 char *token[3]; 220 char *name; 221 uint64_t start; 222 uint64_t len; 223 int i, ret; 224 225 if (strnlen(val, sizeof(buf)) >= sizeof(buf)) 226 parse_err("parameter too long\n"); 227 228 strcpy(str, val); 229 kill_final_newline(str); 230 231 for (i = 0; i < 3; i++) 232 token[i] = strsep(&str, ","); 233 234 if (str) 235 parse_err("too many arguments\n"); 236 237 if (!token[2]) 238 parse_err("not enough arguments\n"); 239 240 ret = parse_name(&name, token[0]); 241 if (ret) 242 return ret; 243 244 ret = parse_num64(&start, token[1]); 245 if (ret) { 246 parse_err("illegal start address\n"); 247 goto error; 248 } 249 250 ret = parse_num64(&len, token[2]); 251 if (ret) { 252 parse_err("illegal device length\n"); 253 goto error; 254 } 255 256 ret = register_device(name, start, len); 257 if (ret) 258 goto error; 259 260 pr_info("%s device: %#llx at %#llx\n", name, len, start); 261 return 0; 262 263 error: 264 kfree(name); 265 return ret; 266 } 267 268 static int phram_param_call(const char *val, const struct kernel_param *kp) 269 { 270 #ifdef MODULE 271 return phram_setup(val); 272 #else 273 /* 274 * If more parameters are later passed in via 275 * /sys/module/phram/parameters/phram 276 * and init_phram() has already been called, 277 * we can parse the argument now. 278 */ 279 280 if (phram_init_called) 281 return phram_setup(val); 282 283 /* 284 * During early boot stage, we only save the parameters 285 * here. We must parse them later: if the param passed 286 * from kernel boot command line, phram_param_call() is 287 * called so early that it is not possible to resolve 288 * the device (even kmalloc() fails). Defer that work to 289 * phram_setup(). 290 */ 291 292 if (strlen(val) >= sizeof(phram_paramline)) 293 return -ENOSPC; 294 strcpy(phram_paramline, val); 295 296 return 0; 297 #endif 298 } 299 300 module_param_call(phram, phram_param_call, NULL, NULL, 0200); 301 MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\""); 302 303 304 static int __init init_phram(void) 305 { 306 int ret = 0; 307 308 #ifndef MODULE 309 if (phram_paramline[0]) 310 ret = phram_setup(phram_paramline); 311 phram_init_called = 1; 312 #endif 313 314 return ret; 315 } 316 317 static void __exit cleanup_phram(void) 318 { 319 unregister_devices(); 320 } 321 322 module_init(init_phram); 323 module_exit(cleanup_phram); 324 325 MODULE_LICENSE("GPL"); 326 MODULE_AUTHOR("Joern Engel <joern@wh.fh-wedel.de>"); 327 MODULE_DESCRIPTION("MTD driver for physical RAM"); 328