Subversion Repositories Kolibri OS

Rev

Rev 5363 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5363 Rev 8037
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
$Revision: 5363 $
8
$Revision: 8037 $
9
 
-
 
10
; Memory management for USB structures.
9
 
11
; Protocol layer uses the common kernel heap malloc/free.
10
; Memory management for slab structures.
12
; Hardware layer has special requirements:
11
; The allocator meets special requirements:
13
; * memory blocks should be properly aligned
12
; * memory blocks are properly aligned
14
; * memory blocks should not cross page boundary
13
; * memory blocks do not cross page boundary
15
; Hardware layer allocates fixed-size blocks.
14
; The allocator manages fixed-size blocks.
16
; Thus, the specific allocator is quite easy to write:
15
; Thus, the specific allocator works as follows:
Line 17... Line 16...
17
; allocate one page, split into blocks, maintain the single-linked
16
; allocate one page, split into blocks, maintain the single-linked
Line 18... Line 17...
18
; list of all free blocks in each page.
17
; list of all free blocks in each page.
Line 19... Line 18...
19
 
18
 
20
; Note: size must be a multiple of required alignment.
19
; Note: size must be a multiple of required alignment.
21
 
20
 
22
; Data for one pool: dd pointer to the first page, MUTEX lock.
21
; Data for one pool: dd pointer to the first page, MUTEX lock.
23
 
22
 
24
; Allocator for fixed-size blocks: allocate a block.
23
; Allocator for fixed-size blocks: allocate a block.
25
; [ebx-4] = pointer to the first page, ebx = pointer to MUTEX structure.
24
; [ebx-4] = pointer to the first page, ebx = pointer to MUTEX structure.
26
proc usb_allocate_common
25
proc slab_alloc
Line 53... Line 52...
53
; 2e. Get the pointer to the next free block.
52
; 2e. Get the pointer to the next free block.
54
        mov     ecx, [eax]
53
        mov     ecx, [eax]
55
; 2f. Update the pointer to the first free block from eax to ecx.
54
; 2f. Update the pointer to the first free block from eax to ecx.
56
; Normally [edx-8] still contains eax, if so, atomically set it to ecx
55
; Normally [edx-8] still contains eax, if so, atomically set it to ecx
57
; and proceed to 3.
56
; and proceed to 3.
58
; However, the price of simplicity of usb_free_common (in particular, it
57
; However, the price of simplicity of slab_free (in particular, it doesn't take
59
; doesn't take the lock) is that [edx-8] could (rarely) be changed while
58
; the lock) is that [edx-8] could (rarely) be changed while we processed steps
60
; we processed steps 2d+2e. If so, return to 2d and retry.
59
; 2d+2e. If so, return to 2d and retry.
61
        lock cmpxchg [edx-8], ecx
60
        lock cmpxchg [edx-8], ecx
62
        jnz     @b
61
        jnz     @b
63
.return:
62
.return:
64
; 3. Release the lock taken in step 1 and return.
63
; 3. Release the lock taken in step 1 and return.
65
        push    eax
64
        push    eax
Line 97... Line 96...
97
        sub     ecx, [.size]
96
        sub     ecx, [.size]
98
        and     dword [ecx], 0
97
        and     dword [ecx], 0
99
; 8. Return (start of page).
98
; 8. Return (start of page).
100
        jmp     .return
99
        jmp     .return
101
.nomemory:
100
.nomemory:
102
        dbgstr 'no memory for USB descriptor'
101
        dbgstr 'no memory for slab allocation'
103
        xor     eax, eax
102
        xor     eax, eax
104
        jmp     .return
103
        jmp     .return
105
endp
104
endp
Line 106... Line 105...
106
 
105
 
107
; Allocator for fixed-size blocks: free a block.
106
; Allocator for fixed-size blocks: free a block.
108
proc usb_free_common
107
proc slab_free
109
        push    ecx edx
108
        push    ecx edx
110
virtual at esp
109
virtual at esp
111
        rd      2       ; saved registers
110
        rd      2       ; saved registers
112
        dd      ?       ; return address
111
        dd      ?       ; return address
Line 122... Line 121...
122
        lock cmpxchg [edx+1-8], ecx
121
        lock cmpxchg [edx+1-8], ecx
123
        jnz     @b
122
        jnz     @b
124
        pop     edx ecx
123
        pop     edx ecx
125
        ret     4
124
        ret     4
126
endp
125
endp
127
 
-
 
128
; Helper procedure: translate physical address in ecx
-
 
129
; of some transfer descriptor to linear address.
-
 
130
; in: eax = address of first page
-
 
131
proc usb_td_to_virt
-
 
132
; Traverse all pages used for transfer descriptors, looking for the one
-
 
133
; with physical address as in ecx.
-
 
134
@@:
-
 
135
        test    eax, eax
-
 
136
        jz      .zero
-
 
137
        push    eax
-
 
138
        call    get_pg_addr
-
 
139
        sub     eax, ecx
-
 
140
        jz      .found
-
 
141
        cmp     eax, -0x1000
-
 
142
        ja      .found
-
 
143
        pop     eax
-
 
144
        mov     eax, [eax+0x1000-4]
-
 
145
        jmp     @b
-
 
146
.found:
-
 
147
; When found, combine page address from eax with page offset from ecx.
-
 
148
        pop     eax
-
 
149
        and     ecx, 0xFFF
-
 
150
        add     eax, ecx
-
 
151
.zero:
-
 
152
        ret
-
 
153
endp
-