1 /* 2 * Copyright (C) 2007 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <gpxe/blockdev.h> 22 #include <gpxe/ramdisk.h> 23 24 /** 25 * @file 26 * 27 * RAM disks 28 * 29 */ 30 31 static inline __attribute__ (( always_inline )) struct ramdisk * 32 block_to_ramdisk ( struct block_device *blockdev ) { 33 return container_of ( blockdev, struct ramdisk, blockdev ); 34 } 35 36 /** 37 * Read block 38 * 39 * @v blockdev Block device 40 * @v block Block number 41 * @v count Block count 42 * @v buffer Data buffer 43 * @ret rc Return status code 44 */ 45 static int ramdisk_read ( struct block_device *blockdev, uint64_t block, 46 unsigned long count, userptr_t buffer ) { 47 struct ramdisk *ramdisk = block_to_ramdisk ( blockdev ); 48 unsigned long offset = ( block * blockdev->blksize ); 49 unsigned long length = ( count * blockdev->blksize ); 50 51 DBGC ( ramdisk, "RAMDISK %p reading [%lx,%lx)\n", 52 ramdisk, offset, length ); 53 54 memcpy_user ( buffer, 0, ramdisk->data, offset, length ); 55 return 0; 56 } 57 58 /** 59 * Write block 60 * 61 * @v blockdev Block device 62 * @v block Block number 63 * @v count Block count 64 * @v buffer Data buffer 65 * @ret rc Return status code 66 */ 67 static int ramdisk_write ( struct block_device *blockdev, uint64_t block, 68 unsigned long count, userptr_t buffer ) { 69 struct ramdisk *ramdisk = block_to_ramdisk ( blockdev ); 70 unsigned long offset = ( block * blockdev->blksize ); 71 unsigned long length = ( count * blockdev->blksize ); 72 73 DBGC ( ramdisk, "RAMDISK %p writing [%lx,%lx)\n", 74 ramdisk, offset, length ); 75 76 memcpy_user ( ramdisk->data, offset, buffer, 0, length ); 77 return 0; 78 } 79 80 static struct block_device_operations ramdisk_operations = { 81 .read = ramdisk_read, 82 .write = ramdisk_write 83 }; 84 85 int init_ramdisk ( struct ramdisk *ramdisk, userptr_t data, size_t len, 86 unsigned int blksize ) { 87 88 if ( ! blksize ) 89 blksize = 512; 90 91 ramdisk->data = data; 92 ramdisk->blockdev.op = &ramdisk_operations; 93 ramdisk->blockdev.blksize = blksize; 94 ramdisk->blockdev.blocks = ( len / blksize ); 95 96 return 0; 97 } 98