You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.1 KiB
107 lines
3.1 KiB
/*
|
|
* Utility functions operating the devices. support only RAM disk device. added @lab4_1.
|
|
*/
|
|
|
|
#include "ramdev.h"
|
|
#include "vfs.h"
|
|
#include "pmm.h"
|
|
#include "riscv.h"
|
|
#include "util/types.h"
|
|
#include "util/string.h"
|
|
#include "spike_interface/spike_utils.h"
|
|
#include "rfs.h"
|
|
|
|
struct rfs_device *rfs_device_list[MAX_RAMDISK_COUNT];
|
|
|
|
//
|
|
// write the content stored in "buff" to the "blkno"^th block of disk.
|
|
//
|
|
int ramdisk_write(struct rfs_device *rfs_device, int blkno){
|
|
if ( blkno < 0 || blkno >= RAMDISK_BLOCK_COUNT )
|
|
panic("ramdisk_write: write block No %d out of range!\n", blkno);
|
|
void * dst = (void *)((uint64)rfs_device->d_address + blkno * RAMDISK_BLOCK_SIZE);
|
|
memcpy(dst, rfs_device->iobuffer, RAMDISK_BLOCK_SIZE);
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// read the "blkno"^th block from the RAM disk and store its content into buffer.
|
|
//
|
|
int ramdisk_read(struct rfs_device *rfs_device, int blkno){
|
|
if ( blkno < 0 || blkno >= RAMDISK_BLOCK_COUNT )
|
|
panic("ramdisk_read: read block No out of range!\n");
|
|
void * src = (void *)((uint64)rfs_device->d_address + blkno * RAMDISK_BLOCK_SIZE);
|
|
memcpy(rfs_device->iobuffer, src, RAMDISK_BLOCK_SIZE);
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// alloc RAMDISK_BLOCK_COUNT continuous pages (blocks) for the RAM Disk
|
|
// setup an vfs node, initialize RAM disk device, and attach the device with the vfs node.
|
|
//
|
|
struct device *init_rfs_device(const char *dev_name) {
|
|
// find rfs in registered fs list
|
|
struct file_system_type *fs_type = NULL;
|
|
for (int i = 0; i < MAX_SUPPORTED_FS; i++) {
|
|
if (fs_list[i] != NULL && fs_list[i]->type_num == RFS_TYPE) {
|
|
fs_type = fs_list[i];
|
|
break;
|
|
}
|
|
}
|
|
if (!fs_type) {
|
|
panic("No RFS file system found!\n");
|
|
}
|
|
|
|
// alloc blocks for the RAM Disk
|
|
void *curr_addr = NULL;
|
|
void *last_addr = NULL;
|
|
void *ramdisk_addr = NULL;
|
|
for ( int i = 0; i < RAMDISK_BLOCK_COUNT; ++ i ){
|
|
last_addr = curr_addr;
|
|
curr_addr = alloc_page();
|
|
if ( last_addr != NULL && last_addr - curr_addr != PGSIZE ){
|
|
panic("RAM Disk0: address is discontinuous!\n");
|
|
}
|
|
}
|
|
ramdisk_addr = curr_addr;
|
|
|
|
// find a free rfs device
|
|
struct rfs_device **rfs_device = NULL;
|
|
int device_id = 0;
|
|
for (int i = 0; i < MAX_RAMDISK_COUNT; i++) {
|
|
if (rfs_device_list[i] == NULL) {
|
|
rfs_device = &rfs_device_list[i];
|
|
device_id = i;
|
|
break;
|
|
}
|
|
}
|
|
if (!rfs_device) {
|
|
panic("RAM Disk0: no free device!\n");
|
|
}
|
|
|
|
*rfs_device = (struct rfs_device *)alloc_page();
|
|
(*rfs_device)->d_blocks = RAMDISK_BLOCK_COUNT;
|
|
(*rfs_device)->d_blocksize = RAMDISK_BLOCK_SIZE;
|
|
(*rfs_device)->d_write = ramdisk_write;
|
|
(*rfs_device)->d_read = ramdisk_read;
|
|
(*rfs_device)->d_address = ramdisk_addr;
|
|
(*rfs_device)->iobuffer = alloc_page();
|
|
|
|
// allocate a vfs device
|
|
struct device * device = (struct device *)alloc_page();
|
|
// set the device name and index
|
|
strcpy(device->dev_name, dev_name);
|
|
device->dev_id = device_id;
|
|
device->fs_type = fs_type;
|
|
|
|
// add the device to the vfs device list
|
|
for(int i = 0; i < MAX_VFS_DEV; i++) {
|
|
if (vfs_dev_list[i] == NULL) {
|
|
vfs_dev_list[i] = device;
|
|
break;
|
|
}
|
|
}
|
|
|
|
sprint("%s: base address of %s is: %p\n",dev_name, dev_name, ramdisk_addr);
|
|
return device;
|
|
} |