root/Whitix/trunk/memory/shmem.c

Revision 1796, 4.6 KB (checked in by mwhitworth, 3 years ago)

Add checks, convert printf (commented out) to Keprint.

Line 
1/*  This file is part of Whitix.
2 *
3 *  Whitix is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  Whitix is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with Whitix; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16 *
17 */
18
19#include <fs/vfs.h>
20#include <vmm.h>
21#include <llist.h>
22#include <malloc.h>
23#include <typedefs.h>
24#include <i386/i386.h>
25#include <slab.h>
26#include <user_acc.h>
27#include <sys.h>
28#include <module.h>
29#include <print.h>
30
31#define SHMEM_MAX_DESCS         10
32
33struct SharedMemoryDesc
34{
35        int creatorPid;
36        DWORD size;
37        DWORD* pages;
38};
39
40struct SharedMemoryDesc* shMemDescs[SHMEM_MAX_DESCS];
41
42int ShMemNoPage(struct VMArea* area, DWORD address, DWORD offset);
43int ShMemAddPage(struct VMArea* area, DWORD address);
44
45struct VmAreaOps shMemOps=
46{
47        .handleNoPage = ShMemNoPage,
48        .addPage = ShMemAddPage,
49};
50
51static struct SharedMemoryDesc* ShMemGetDesc(int i)
52{
53        if (i < 0 || i >= SHMEM_MAX_DESCS)
54                return NULL;
55
56        return shMemDescs[i];
57}
58
59int SharedMemCreate(size_t size, int flags)
60{
61        int numPages=PAGE_ALIGN_UP(size) >> PAGE_SHIFT;
62        int i, id;
63        struct SharedMemoryDesc* shDesc;
64
65        if (!numPages)
66                return -EINVAL;
67
68        /* Find an empty shared memory description slot. */
69        for (i=0; i<SHMEM_MAX_DESCS; i++)
70                /* Descriptor slot not occupied? */
71                if (!shMemDescs[i])
72                        break;
73
74        if (i == SHMEM_MAX_DESCS)
75                return -EMFILE;
76
77        shMemDescs[i]=shDesc=(struct SharedMemoryDesc*)MemAlloc(sizeof(struct SharedMemoryDesc));
78
79        id=i;
80
81        if (!shDesc)
82                return -ENOMEM;
83
84        /* Fill in the shared memory descriptor */
85        shDesc->size=PAGE_ALIGN_UP(size);
86        shDesc->pages=(DWORD*)MemAlloc(sizeof(DWORD)*numPages);
87
88        if (!shDesc->pages)
89                return -ENOMEM;
90
91        for (i=0; i<numPages; i++)
92                shDesc->pages[i]=0;
93
94        return id+1;
95}
96
97int SysSharedMemoryGet(unsigned int key, size_t size, int flags)
98{
99//      KePrint("SysSharedMemoryGet(%d, %u)\n", key, size);
100        if (key == 0)
101                return SharedMemCreate(size, flags);
102        else{
103                KePrint("SysSharedMemoryGet: key > 0\n");
104                return -EINVAL;
105        }
106
107        return 0;
108}
109
110DWORD SysSharedMemoryAttach(int id, DWORD address, int flags)
111{
112        struct SharedMemoryDesc* desc=ShMemGetDesc(id-1);
113
114//      KePrint("%s: SysSharedMemoryAttach(%d, %#X), %#X, size = %#X\n", current->name, id, address, desc, desc->size);
115
116        if (!desc)
117                return 0;
118
119        return MMapDo(current, NULL, address, desc->size, 7, 0, MMAP_PRIVATE, &shMemOps);
120}
121
122/* FIXME: Rewrite. */
123struct SharedMemoryDesc* ShMemFind(DWORD length)
124{
125        /* FIXME: Have private field for VMArea. */
126        int i=0;
127
128        for (i=0; i<SHMEM_MAX_DESCS; i++)
129        {
130                /* FIXME: Hack! */
131                if (shMemDescs[i] && shMemDescs[i]->size == length)
132                        break;
133        }
134
135        if (i == SHMEM_MAX_DESCS)
136                return NULL;
137
138        return shMemDescs[i];
139}
140
141int ShMemAddPage(struct VMArea* area, DWORD address)
142{
143        struct SharedMemoryDesc* shMem=ShMemFind(area->length);
144        int pageIndex=(address-area->start) >> PAGE_SHIFT;
145
146//      KePrint("pageIndex = %d\n", pageIndex);
147
148        if (!shMem)
149                return -EFAULT;
150
151        while (1);
152
153        return 0;
154}
155
156/* TODO: Try to merge with the general mmap code perhaps? */
157int ShMemNoPage(struct VMArea* area, DWORD address, DWORD offset)
158{
159        int pageIndex=offset >> PAGE_SHIFT;
160        struct SharedMemoryDesc* shMem=ShMemFind(area->length);
161
162        if (!shMem)
163                return -EFAULT;
164
165        if (!shMem->pages[pageIndex])
166                shMem->pages[pageIndex]=PageAlloc()->physAddr;
167
168//      KePrint("%s: ShMemNoPage(%d) = %#X\n", current->name, pageIndex, shMem->pages[pageIndex]);
169
170        /* HACK: Need to have flag and reconsider whether should map here. */
171        struct VNode* vNode;
172
173        NameToVNode(&vNode,DEVICES_PATH "Special/Zero",0, NULL);
174
175        if (area->vNode->id == vNode->id)
176        {
177                VirtMemMapPage(address, shMem->pages[pageIndex], 7);
178                return 0;
179        }
180
181        return -EFAULT;
182}
183
184int SysSharedMemoryControl(int id, int command, void* buffer)
185{
186        KePrint("SysSharedMemoryControl(%d)\n", id);
187        return 0;
188}
189
190int SysSharedMemoryDetach(const void* address)
191{
192        KePrint("SysSharedMemoryDetach(%#X)\n", address);
193        return 0;
194}
195
196struct SysCall shMemSysCalls[]=
197{
198        SysEntry(SysSharedMemoryGet, 12),
199        SysEntry(SysSharedMemoryAttach, 12),
200        SysEntry(SysSharedMemoryControl, 12),
201        SysEntry(SysSharedMemoryDetach, 4),
202        SysEntryEnd(),
203};
204
205int ShMemInit()
206{
207        SysRegisterRange(SYS_SHMEM_BASE, shMemSysCalls);
208        return 0;
209}
210
211ModuleInit(ShMemInit);
Note: See TracBrowser for help on using the browser.