Subversion Repositories Kolibri OS

Rev

Rev 5363 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5363 yogev_ezra 3
;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;; RAMDISK functions                                            ;;
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
 
9
$Revision: 8064 $
10
 
4273 clevermous 11
iglobal
12
align 4
13
ramdisk_functions:
14
        dd      .size
15
        dd      0       ; no close() function
16
        dd      0       ; no closemedia() function
17
        dd      ramdisk_querymedia
18
        dd      ramdisk_read
19
        dd      ramdisk_write
20
        dd      0       ; no flush() function
21
        dd      ramdisk_adjust_cache_size
22
.size = $ - ramdisk_functions
23
endg
2288 clevermous 24
 
4273 clevermous 25
iglobal
26
align 4
27
ramdisk_actual_size     dd      RAMDISK_CAPACITY
2288 clevermous 28
endg
29
 
4273 clevermous 30
; This function is called early in boot process.
31
; It creates filesystem /rd/1 based on raw image data loaded by somebody before
32
; to memory named as RAMDISK with max size RAMDISK_CAPACITY, may be less.
33
proc ramdisk_init
2288 clevermous 34
iglobal
4273 clevermous 35
ramdisk_name    db      'rd',0
2288 clevermous 36
endg
4273 clevermous 37
        push    ebx esi ; save used registers to be stdcall
38
; 1. Register the device and the (always inserted) media in the disk subsystem.
39
        stdcall disk_add, ramdisk_functions, ramdisk_name, 0, 0
40
        test    eax, eax
41
        jz      .fail
42
        mov     ebx, eax
43
        stdcall disk_media_changed, eax, 1
44
; 2. We don't know actual size of loaded image,
45
; so try to calculate it using partition structure,
46
; assuming that file systems fill the real size based on contents of the partition.
47
; 2a. Prepare for loop over partitions.
8064 dunkaist 48
        xor     eax, eax
2288 clevermous 49
        xor     ecx, ecx
4273 clevermous 50
        xor     edx, edx
51
; 2b. Check that at least one partition was recognized.
52
        cmp     [ebx+DISK.NumPartitions], ecx
53
        jz      .fail
54
; 2c. Loop over partitions.
55
.partitions:
56
; For every partition, set edx to maximum between edx and end of partition.
57
        mov     esi, [ebx+DISK.Partitions]
58
        mov     esi, [esi+ecx*4]
59
        mov     eax, dword [esi+PARTITION.FirstSector]
60
        add     eax, dword [esi+PARTITION.Length]
61
        cmp     eax, edx
62
        jb      @f
63
        mov     edx, eax
2288 clevermous 64
@@:
65
        inc     ecx
4273 clevermous 66
        cmp     ecx, [ebx+DISK.NumPartitions]
67
        jb      .partitions
68
; 3. Reclaim unused memory, if any.
69
        mov     [ramdisk_actual_size], edx
70
        add     edx, 7  ; aligning up
71
        shr     edx, 3  ; 512-byte sectors -> 4096-byte pages
72
        mov     esi, RAMDISK_CAPACITY / 8       ; aligning down
73
        sub     esi, edx
74
        jbe     .no_reclaim
75
        shl     edx, 12
76
        add     edx, RAMDISK - OS_BASE
2288 clevermous 77
@@:
4273 clevermous 78
        mov     eax, edx
79
        call    free_page
80
        add     edx, 0x1000
81
        dec     esi
2288 clevermous 82
        jnz     @b
4273 clevermous 83
.no_reclaim:
8064 dunkaist 84
        mov     eax, ebx
4273 clevermous 85
        pop     esi ebx ; restore used registers to be stdcall
2288 clevermous 86
        ret
4273 clevermous 87
.fail:
88
        dbgstr 'Failed to initialize ramdisk'
89
        pop     esi ebx ; restore used registers to be stdcall
2288 clevermous 90
        ret
4273 clevermous 91
endp
2288 clevermous 92
 
4273 clevermous 93
; Returns information about disk media.
94
proc ramdisk_querymedia
95
  virtual at esp+4
96
    .userdata dd ?
97
    .info dd ?
98
  end virtual
99
; Media is always present, sector size is always 512 bytes.
100
        mov     edx, [.userdata]
101
        mov     ecx, [.info]
102
        mov     [ecx+DISKMEDIAINFO.Flags], 0
103
        mov     [ecx+DISKMEDIAINFO.SectorSize], 512
104
        mov     eax, [ramdisk_actual_size]
105
        mov     dword [ecx+DISKMEDIAINFO.Capacity], eax
106
        mov     dword [ecx+DISKMEDIAINFO.Capacity+4], 0
107
; Return zero as an indicator of success.
2288 clevermous 108
        xor     eax, eax
4273 clevermous 109
        retn    8
110
endp
2288 clevermous 111
 
4273 clevermous 112
; Common procedure for reading and writing.
113
; operation = 0 for reading, operation = 1 for writing.
114
; Arguments of ramdisk_read and ramdisk_write are the same.
115
macro ramdisk_read_write operation
116
{
117
        push    esi edi         ; save used registers to be stdcall
118
        mov     esi, [userdata]
119
        mov     edi, [numsectors_ptr]
120
; 1. Determine number of sectors to be transferred.
121
; This is either the requested number of sectors or number of sectors
122
; up to the disk boundary, depending of what is less.
2288 clevermous 123
        xor     ecx, ecx
4273 clevermous 124
; 1a. Test whether [start_sector] is less than RAMDISK_CAPACITY.
125
; If so, calculate number of sectors between [start_sector] and RAMDISK_CAPACITY.
126
; Otherwise, the actual number of sectors is zero.
127
        cmp     dword [start_sector+4], ecx
128
        jnz     .got_number
129
        mov     eax, [ramdisk_actual_size]
130
        sub     eax, dword [start_sector]
131
        jbe     .got_number
132
; 1b. Get the requested number of sectors.
133
        mov     ecx, [edi]
134
; 1c. If it is greater than number of sectors calculated in 1a, use the value
135
; from 1a.
2288 clevermous 136
        cmp     ecx, eax
4273 clevermous 137
        jb      .got_number
138
        mov     ecx, eax
139
.got_number:
140
; 2. Compare the actual number of sectors with requested. If they are
141
; equal, set eax (it will be the returned value) to zero. Otherwise,
142
; use DISK_STATUS_END_OF_MEDIA.
3525 clevermous 143
        xor     eax, eax
4273 clevermous 144
        cmp     ecx, [edi]
3525 clevermous 145
        jz      @f
4273 clevermous 146
        mov     al, DISK_STATUS_END_OF_MEDIA
3525 clevermous 147
@@:
4273 clevermous 148
; 3. Store the actual number of sectors.
149
        mov     [edi], ecx
150
; 4. Calculate source and destination addresses.
151
if operation = 0 ; reading?
152
        mov     esi, dword [start_sector]
153
        shl     esi, 9
154
        add     esi, RAMDISK
155
        mov     edi, [buffer]
156
else ; writing?
157
        mov     edi, dword [start_sector]
2288 clevermous 158
        shl     edi, 9
4273 clevermous 159
        add     edi, RAMDISK
160
        mov     esi, [buffer]
161
end if
162
; 5. Calculate number of dwords to be transferred.
163
        shl     ecx, 9-2
164
; 6. Copy data.
2288 clevermous 165
        rep movsd
4273 clevermous 166
; 7. Return. The value in eax was calculated in step 2.
167
        pop     edi esi         ; restore used registers to be stdcall
168
}
2288 clevermous 169
 
4273 clevermous 170
; Reads one or more sectors from the device.
171
proc ramdisk_read userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword
172
        ramdisk_read_write 0
2288 clevermous 173
        ret
4273 clevermous 174
endp
2288 clevermous 175
 
4273 clevermous 176
; Writes one or more sectors to the device.
177
proc ramdisk_write userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword
178
        ramdisk_read_write 1
2288 clevermous 179
        ret
4273 clevermous 180
endp
2288 clevermous 181
 
4273 clevermous 182
; The kernel calls this function when initializing cache subsystem for
183
; the media. This call allows the driver to adjust the cache size.
184
proc ramdisk_adjust_cache_size
185
  virtual at esp+4
186
    .userdata dd ?
187
    .suggested_size dd ?
188
  end virtual
189
; Since ramdisk does not need cache, just return 0.
2288 clevermous 190
        xor     eax, eax
4273 clevermous 191
        retn    8
192
endp