about summary refs log tree commit diff stats
path: root/kernel.soso/ramdisk.c
blob: d092fc993124d5333d8d372bcdee91ffac87c3e2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "ramdisk.h"
#include "alloc.h"
#include "fs.h"
#include "devfs.h"

typedef struct Ramdisk {
    uint8* buffer;
    uint32 size;
} Ramdisk;

#define RAMDISK_BLOCKSIZE 512

static BOOL open(File *file, uint32 flags);
static void close(File *file);
static int32 readBlock(FileSystemNode* node, uint32 blockNumber, uint32 count, uint8* buffer);
static int32 writeBlock(FileSystemNode* node, uint32 blockNumber, uint32 count, uint8* buffer);
static int32 ioctl(File *node, int32 request, void * argp);

BOOL createRamdisk(const char* devName, uint32 size) {
    Ramdisk* ramdisk = kmalloc(sizeof(Ramdisk));
    ramdisk->size = size;
    ramdisk->buffer = kmalloc(size);

    Device device;
    memset((uint8*)&device, 0, sizeof(device));
    strcpy(device.name, devName);
    device.deviceType = FT_BlockDevice;
    device.open = open;
    device.close = close;
    device.readBlock = readBlock;
    device.writeBlock = writeBlock;
    device.ioctl = ioctl;
    device.privateData = ramdisk;

    if (registerDevice(&device)) {
        return TRUE;
    }

    kfree(ramdisk->buffer);
    kfree(ramdisk);

    return FALSE;
}

static BOOL open(File *file, uint32 flags) {
    return TRUE;
}

static void close(File *file) {
}

static int32 readBlock(FileSystemNode* node, uint32 blockNumber, uint32 count, uint8* buffer) {
    Ramdisk* ramdisk = (Ramdisk*)node->privateNodeData;

    uint32 location = blockNumber * RAMDISK_BLOCKSIZE;
    uint32 size = count * RAMDISK_BLOCKSIZE;

    if (location + size > ramdisk->size) {
        return -1;
    }

    beginCriticalSection();

    memcpy(buffer, ramdisk->buffer + location, size);

    endCriticalSection();

    return 0;
}

static int32 writeBlock(FileSystemNode* node, uint32 blockNumber, uint32 count, uint8* buffer) {
    Ramdisk* ramdisk = (Ramdisk*)node->privateNodeData;

    uint32 location = blockNumber * RAMDISK_BLOCKSIZE;
    uint32 size = count * RAMDISK_BLOCKSIZE;

    if (location + size > ramdisk->size) {
        return -1;
    }

    beginCriticalSection();

    memcpy(ramdisk->buffer + location, buffer, size);

    endCriticalSection();

    return 0;
}

static int32 ioctl(File *node, int32 request, void * argp) {
    Ramdisk* ramdisk = (Ramdisk*)node->node->privateNodeData;

    uint32* result = (uint32*)argp;

    switch (request) {
    case IC_GetSectorCount:
        *result = ramdisk->size / RAMDISK_BLOCKSIZE;
        return 0;
        break;
    case IC_GetSectorSizeInBytes:
        *result = RAMDISK_BLOCKSIZE;
        return 0;
        break;
    default:
        break;
    }

    return -1;
}