SayoriOS  0.3.3
dpm.c
См. документацию.
1 
10 #include <io/ports.h>
11 #include <drv/disk/dpm.h>
12 #include "mem/vmm.h"
13 bool dpm_debug = false;
14 
15 DPM_Disk DPM_Disks[32] = {0};
16 
17 int dpm_searchFreeIndex(int Index) {
18  Index = (Index < 0 || Index > 25 ? 0 : Index);
19 
20  for (int i = Index; i < 32; i++){
21  if (DPM_Disks[i].Ready == 1)
22  continue;
23 
24  return i;
25  }
26 
27  for (int i = 4; i < 32; i++){
28  if (DPM_Disks[i].Ready == 1)
29  continue;
30 
31  return i;
32  }
33 
34  return -1;
35 }
36 
37 void dpm_fnc_write(char Letter, dpm_disk_rw_cmd Read, dpm_disk_rw_cmd Write) {
38  int Index = Letter - 65;
39 
40  Index = (Index > 32 ? Index - 32 : Index);
41  Index = (Index < 0 || Index > 25 ? 0 : Index);
42 
43 
44  if (DPM_Disks[Index].Ready == 0 || DPM_Disks[Index].Status == 0)
45  return;
46 
47  DPM_Disks[Index].Read = Read;
48  DPM_Disks[Index].Write = Write;
49 }
50 
51 void* dpm_metadata_read(char Letter){
52  int Index = Letter - 65;
53 
54  Index = (Index > 32 ? Index - 32 : Index);
55  Index = (Index < 0 || Index > 25 ? 0 : Index);
56 
57  if (DPM_Disks[Index].Ready == 0 || DPM_Disks[Index].Status == 0)
58  return 0;
59 
60  return DPM_Disks[Index].Reserved;
61 }
62 
63 void dpm_metadata_write(char Letter, uint32_t Addr){
64  int Index = Letter - 65;
65 
66  Index = (Index > 32 ? Index - 32 : Index);
67  Index = (Index < 0 || Index > 25 ? 0 : Index);
68 
69  DPM_Disks[Index].Reserved = (void*)Addr;
70 }
71 
82 size_t dpm_read(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, void *Buffer){
83  int Index = Letter - 65;
84 
85  Index = (Index > 32 ? Index - 32 : Index);
86  Index = (Index < 0 || Index > 25 ? 0 : Index);
87 
88  if (DPM_Disks[Index].Ready == 0 || DPM_Disks[Index].Status == 0)
89  return DPM_ERROR_NOT_READY;
90 
91  if (DPM_Disks[Index].AddrMode == 2){
92  // Диск является частью ОЗУ, поэтому мы просто копируем данные оттуда
93  if (dpm_debug)qemu_log("[DPM] [2] An attempt to read data in 'Disk %c' from position %x to the number of %d bytes.", Index+65, DPM_Disks[Index].Point+low_offset, Size);
94  memcpy(Buffer, (void *) (DPM_Disks[Index].Point + low_offset), Size);
95 
96  return Size;
97  } else if (DPM_Disks[Index].AddrMode == 3){
98  // Режим 3, предполагает что вы указали функцию для чтения и записи с диска
99  if (dpm_debug)qemu_log("[DPM] [3] An attempt to read data in 'Disk %c' from position %x to the number of %d bytes.", Index+65, DPM_Disks[Index].Point+low_offset, Size);
100  if (DPM_Disks[Index].Read == 0){
101  qemu_err("[DPM] [3] Function 404");
102  return 0;
103  }
104 
105  return DPM_Disks[Index].Read(Index,high_offset,low_offset,Size,Buffer);
106  } else {
107  if (dpm_debug)qemu_log("[DPM] This functionality has not been implemented yet.");
108  }
109 
110  return DPM_ERROR_NO_READ;
111 }
112 
123 size_t dpm_write(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, char* Buffer){
124  int Index = Letter - 65;
125 
126  Index = (Index > 32 ? Index - 32 : Index);
127  Index = (Index < 0 || Index > 25 ? 0 : Index);
128 
129  if (DPM_Disks[Index].Ready == 0 || DPM_Disks[Index].Status == 0)
130  return DPM_ERROR_NOT_READY;
131 
132  if (DPM_Disks[Index].AddrMode == 2){
133  // Диск является частью ОЗУ, поэтому мы просто копируем данные туда
134  // Опастна! Если не знать, что делать!
135  if (dpm_debug)qemu_log("[DPM] [2] An attempt to write data in 'Disk %c' from position %x to the number of %d bytes.", Index+65, DPM_Disks[Index].Point+low_offset, Size);
136  memcpy((void *) (DPM_Disks[Index].Point + low_offset), Buffer, Size);
137 
138  return Size;
139  } else if (DPM_Disks[Index].AddrMode == 3){
140  // Режим 3, предполагает что вы указали функцию для чтения и записи с диска
141  if (dpm_debug)qemu_log("[DPM] [3] An attempt to write data in 'Disk %c' from position %x to the number of %d bytes.", Index+65, DPM_Disks[Index].Point+low_offset, Size);
142  if (DPM_Disks[Index].Write == 0){
143  qemu_err("[DPM] [3] No function");
144  return 0;
145  }
146  return DPM_Disks[Index].Write(Index,high_offset,low_offset,Size,Buffer);
147  } else {
148  if (dpm_debug)qemu_log("[DPM] This functionality has not been implemented yet.");
149  }
150 
151  return DPM_ERROR_NO_READ;
152 }
153 
154 int dpm_unmount(char Letter, bool FreeReserved){
155  int Index = Letter - 65;
156 
157  Index = (Index > 32 ? Index - 32 : Index);
158  Index = (Index < 0 || Index > 25 ? 0 : Index);
159 
160  if (DPM_Disks[Index].Ready == 0) return 0;
161 
162  DPM_Disks[Index].Ready = 0;
163 
164  //memcpy(DPM_Disks[Index].Name, NULL, sizeof(NULL));
165  //memcpy(DPM_Disks[Index].Serial, NULL, sizeof(NULL));
166  //memcpy(DPM_Disks[Index].FileSystem, NULL, sizeof(NULL));
167  DPM_Disks[Index].Status = 0;
168  DPM_Disks[Index].Size = 0;
169  DPM_Disks[Index].Sectors = 0;
170  DPM_Disks[Index].SectorSize = 0;
171  DPM_Disks[Index].AddrMode = 0;
172  DPM_Disks[Index].Point = 0;
173 
174  if (FreeReserved && DPM_Disks[Index].Reserved != 0) {
175  kfree(DPM_Disks[Index].Reserved);
176  }
177  return 1;
178 }
179 
187 int dpm_reg(char Letter, char* Name, char* FS, int Status, size_t Size, size_t Sectors, size_t SectorSize, int AddrMode, char* Serial, void *Point){
188  int Index = Letter - 65;
189 
190  Index = (Index > 32 ? Index - 32 : Index);
191  Index = (Index < 0 || Index > 25 ? 0 : Index);
192 
193  if (DPM_Disks[Index].Ready == 1){
194  qemu_warn("[DPM] Warning! This letter is already occupied, and an attempt will be made to search for a free letter.");
195  Index = dpm_searchFreeIndex(Index);
196  if (Index == DPM_ERROR_NO_MOUNT){
197  qemu_warn("[DPM] Sorry, but the disk could not be registered because there is no free letter. Delete the extra devices and try again.");
198  return DPM_ERROR_NO_MOUNT;
199  }
200  qemu_log("[DPM] The drive was assigned the letter '%c'",Index+65);
201  }
202 
203  DPM_Disks[Index].Ready = 1;
204 
205  memcpy(DPM_Disks[Index].Name,Name,strlen(Name));
206  memcpy(DPM_Disks[Index].Serial,Serial,strlen(Serial));
207  memcpy(DPM_Disks[Index].FileSystem,FS,strlen(FS));
208  DPM_Disks[Index].Status = Status;
209  DPM_Disks[Index].Size = Size;
210  DPM_Disks[Index].Sectors = Sectors;
211  DPM_Disks[Index].SectorSize = SectorSize;
212  DPM_Disks[Index].AddrMode = AddrMode;
213  DPM_Disks[Index].Point = Point;
214 
215  qemu_log("[DPM] Disk '%c' is registered!",Index+65);
216  qemu_log(" |-- Name: %s",DPM_Disks[Index].Name);
217  qemu_log(" |-- Serial: %s",DPM_Disks[Index].Serial);
218  qemu_log(" |-- FileSystem: %s",DPM_Disks[Index].FileSystem);
219  qemu_log(" |-- Status: %d",DPM_Disks[Index].Status);
220  // qemu_log(" |-- Size: %d", DPM_Disks[Index].Size); // Most disks have capacity is greater than 4GB (32-bit space), so every disk with capacity greater than 4GB will give a bug. (We need to impelement BigInt?)
221  qemu_log(" |-- Sectors: %d",DPM_Disks[Index].Sectors);
222  qemu_log(" |-- SectorSize: %d",DPM_Disks[Index].SectorSize);
223  qemu_log(" |-- AddrMode: %d",DPM_Disks[Index].AddrMode);
224  qemu_log(" |-- Point: %x",DPM_Disks[Index].Point);
225 
226  return Index;
227 }
228 
229 void dpm_FileSystemUpdate(char Letter, char* FileSystem){
230  Letter -= 65;
231 
232  size_t index;// = (Letter > 32 ? Letter - 32 : Letter);
233  index = (Letter < 0 || Letter > 25 ? 0 : Letter);
234 
235  size_t c = strlen(FileSystem);
236  memset(DPM_Disks[index].FileSystem, 0, 64);
237  memcpy(DPM_Disks[index].FileSystem, FileSystem, (c > 64 || c == 0?64:c));
238 }
239 
240 
241 void dpm_LabelUpdate(char Letter, char* Label){
242  Letter -= 65;
243 
244  size_t index;// = (Letter > 32 ? Letter - 32 : Letter);
245  index = (Letter < 0 || Letter > 25 ? 0 : Letter);
246 
247  size_t c = strlen(Label);
248  memset(DPM_Disks[index].Name, 0, 128);
249  memcpy(DPM_Disks[index].Name, Label, (c > 128 || c == 0?128:c));
250 }
251 
252 size_t dpm_disk_size(char Letter){
253  Letter -= 65;
254 
255  size_t index = (Letter > 32 ? Letter - 32 : Letter);
256  index = (Letter < 0 || Letter > 25 ? 0 : Letter);
257 
258  return (DPM_Disks[index].Size > 0?DPM_Disks[index].Size:0);
259 
260 }
261 
262 DPM_Disk dpm_info(char Letter){
263  Letter -= 65;
264 
265  size_t index;// = (Letter > 32 ? Letter - 32 : Letter);
266  index = (Letter < 0 || Letter > 25 ? 0 : Letter);
267 
268  return DPM_Disks[index];
269 }
270 
size_t dpm_write(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, char *Buffer)
[DPM] Запись данных на диск
Definition: dpm.c:123
void dpm_LabelUpdate(char Letter, char *Label)
Definition: dpm.c:241
int dpm_reg(char Letter, char *Name, char *FS, int Status, size_t Size, size_t Sectors, size_t SectorSize, int AddrMode, char *Serial, void *Point)
[DPM] Регистрация дискового раздела
Definition: dpm.c:187
size_t dpm_read(char Letter, uint64_t high_offset, uint64_t low_offset, size_t Size, void *Buffer)
[DPM] Считывание данных с диска
Definition: dpm.c:82
void dpm_FileSystemUpdate(char Letter, char *FileSystem)
Definition: dpm.c:229
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173