Merge gpxe-for-syslinux
[syslinux.git] / cache.inc
blob59755576b93d9ddd7f41023e6b7220b535170bba
1 ; -*- fundamental -*- ---------------------------------------------------
3 ;   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
5 ;   This program is free software; you can redistribute it and/or modify
6 ;   it under the terms of the GNU General Public License as published by
7 ;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;   Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;   (at your option) any later version; incorporated herein by reference.
11 ; -----------------------------------------------------------------------
13                 section .text
15                 struc cptr
16 .sector:        resd 1                          ; Sector number
17 .prev:          resw 1                          ; LRU pointer to previous (less recent)
18 .next:          resw 1                          ; LRU pointer to next (more recent)
19                 endstruc
20 cptr_size_lg2   equ 3
22 NCacheEntries   equ 65536/SECTOR_SIZE
25 ; initcache: Initialize the cache data structures
27 initcache:
28                 xor eax,eax                     ; We don't care about sector 0
29                 mov di,CachePtrs
30                 mov cx,NCacheEntries+1
31                 mov bx,CachePtrs+NCacheEntries*cptr_size        ; "prev" pointer
32 .loop:
33                 mov [di+cptr.sector],eax        ; Zero sector number
34                 mov [di+cptr.prev],bx           ; Previous pointer
35                 mov [bx+cptr.next],di           ; Previous entry's next pointer
36                 mov bx,di
37                 add di,cptr_size
38                 loop .loop
39                 ret
42 ; getcachesector: Check for a particular sector (EAX) in the sector cache,
43 ;                 and if it is already there, return a pointer in GS:SI
44 ;                 otherwise load it and return said pointer.
46 ;               Assumes CS == DS.
48 getcachesector:
49                 push cx
50                 push bx
51                 push di
52                 mov si,cache_seg
53                 mov gs,si
54                 mov si,CachePtrs+cptr_size      ; Real sector cache pointers
55                 mov cx,NCacheEntries
56 .search:
57                 cmp eax,[si]
58                 jz .hit
59                 add si,cptr_size
60                 loop .search
62 .miss:
63                 TRACER 'M'
64                 ; Need to load it.
65                 push es
66                 push gs
67                 pop es
68                 mov bx,[CachePtrs+cptr.next]    ; "Next most recent than head node"
69                 mov [bx+cptr.sector],eax
70                 mov si,bx
71                 sub bx,CachePtrs+cptr_size
72                 shl bx,SECTOR_SHIFT-cptr_size_lg2       ; Buffer address
73                 pushad
74 %if IS_EXTLINUX
75                 call getonesec_ext
76 %else
77                 call getonesec
78 %endif
79                 popad
80                 pop es
81 .hit:
82                 ; Update LRU, then compute buffer address
83                 TRACER 'H'
85                 ; Remove from current position in the list
86                 mov bx,[si+cptr.prev]
87                 mov di,[si+cptr.next]
88                 mov [bx+cptr.next],di
89                 mov [di+cptr.prev],bx
91                 ; Add to just before head node
92                 mov bx,[CachePtrs+cptr.prev]
93                 mov [si+cptr.prev],bx
94                 mov [bx+cptr.next],si
95                 mov [CachePtrs+cptr.prev],si
96                 mov word [si+cptr.next],CachePtrs
98                 sub si,CachePtrs+cptr_size
99                 shl si,SECTOR_SHIFT-cptr_size_lg2       ; Buffer address
101                 pop di
102                 pop bx
103                 pop cx
104                 ret
106                 section .bss
108                 ; Each CachePtr contains:
109                 ; - Block pointer
110                 ; - LRU previous pointer
111                 ; - LRU next pointer
112                 ; The first entry is the head node of the list
113                 alignb 4
114 CachePtrs       resb (NCacheEntries+1)*cptr_size