--- /dev/null
+#include "core.h"
+
+#include "cache.h"
+#include <stdio.h>
+
+
+/*
+ * Each CachePtr contains:
+ * - Block pointer
+ * - LRU previous pointer
+ * - LRU next pointer
+ * - Block data buffer address
+ *
+ * The cache buffer are pointed to by a cache_head structure.
+ */
+
+
+static struct cache_struct cache_head, cache[MAX_CACHE_ENTRIES];
+static __u8 cache_data[65536];
+static int cache_block_size;
+static int cache_entries;
+
+/**
+ * cache_init:
+ *
+ * Initialize the cache data structres.
+ * regs->eax.l stores the block size
+ *
+ */
+void cache_init(com32sys_t * regs)
+{
+ struct cache_struct *prev, *cur;
+ __u8 *data = cache_data;
+ int block_size = regs->eax.l;
+ int i;
+
+ cache_block_size = block_size;
+ cache_entries = sizeof cache_data / block_size;
+ if (cache_entries > MAX_CACHE_ENTRIES)
+ cache_entries = MAX_CACHE_ENTRIES;
+
+ cache_head.prev = &cache[cache_entries-1];
+ cache_head.prev->next = &cache_head;
+ prev = &cache_head;
+
+ for (i = 0; i < cache_entries; i++) {
+ cur = &cache[i];
+ cur->block = 0;
+ cur->prev = prev;
+ prev->next = cur;
+ cur->data = data;
+ data += block_size;
+ prev = cur++;
+ }
+}
+
+
+extern void getlinsec(void);
+
+void getoneblk(char *buf, __u32 block, int block_size)
+{
+ int sec_per_block = block_size / 512; /* 512==sector size */
+ com32sys_t regs;
+
+
+
+ regs.eax.l = block * sec_per_block;
+ regs.ebp.l = sec_per_block;
+ regs.es = SEG(buf);
+ regs.ebx.w[0] = OFFS(buf);
+
+ call16(getlinsec, ®s, NULL);
+}
+
+
+
+/**
+ * get_cache_block:
+ *
+ * Check for a particular BLOCK in the block cache,
+ * and if it is already there, just do nothing and return;
+ * otherwise load it and updata the relative cache
+ * structre with data pointer.
+ *
+ * it's a test version for my start of merging extlinux into core.
+ * and after I have figured out how to handle the relations between
+ * rm and pm, c and asm, we call call it from C file, so no need
+ * com32sys_t *regs any more.
+ *
+ * @return: the data stores at gs:si
+ *
+ */
+void get_cache_block(com32sys_t * regs)
+{
+ /* let's find it from the end, 'cause the endest is the freshest */
+ struct cache_struct *cs = cache_head.prev;
+ struct cache_struct *head, *last;
+ __u32 block = regs->eax.l;
+ int i;
+
+ if ( !block ) {
+ extern void myputs(const char *);
+ myputs("ERROR: we got a ZERO block number that's not we want!\n");
+ return;
+ }
+
+ /* it's aleardy the freshest, so nothing we need do , just return it */
+ if ( cs->block == block )
+ goto out;
+
+ for ( i = 0; i < cache_entries; i ++ ) {
+ if ( cs->block == block )
+ break;
+ else
+ cs = cs->prev;
+ }
+
+ if ( i == cache_entries ) {
+ /* missed, so we need to load it */
+
+ /* store it at the head of real cache */
+ cs = cache_head.next;
+
+ cs->block = block;
+ getoneblk(cs->data, block, cache_block_size);
+ }
+
+ /* remove cs from current position in list */
+ cs->prev->next = cs->next;
+ cs->next->prev = cs->prev;
+
+
+ /* add to just before head node */
+ last = cache_head.prev;
+ head = &cache_head;
+
+ last->next = cs;
+ cs->prev = last;
+ head->prev = cs;
+ cs->next = head;
+
+ out:
+ regs->gs = SEG(cs->data);
+ regs->esi.w[0]= OFFS(cs->data);
+}
;
; Initialize the metadata cache
;
- call initcache
+ mov eax, [ClustSize]
+ pm_call cache_init
;
; Now, everything is "up and running"... patch kaboom for more
add eax,edx
pop edx
and dx,SECTOR_SIZE-1
- call getcachesector ; Get the group descriptor
+ pm_call get_cache_block ; Get the group descriptor
add si,dx
mov esi,[gs:si+bg_inode_table] ; Get inode table block #
pop eax ; Get inode within group
and dx,SECTOR_SIZE-1
mov [bx+file_in_off],dx
- call getcachesector
+ pm_call get_cache_block
add si,dx
mov cx,EXT2_GOOD_OLD_INODE_SIZE >> 2
mov di,ThisInode
push eax
mov eax,[si+file_in_sec]
mov bx,si
- call getcachesector ; Get inode
+ pm_call get_cache_block ; Get inode
add si,[bx+file_in_off] ; Get *our* inode
pop eax
lea ebx,[i_block+4*eax]
mov ebp,[gs:si+bx]
shl ebp,cl
add eax,ebp
- call getcachesector
+ pm_call get_cache_block
pop bx
and bx,(SECTOR_SIZE >> 2)-1
shl bx,2
mov ebp,[gs:si+bx]
shl ebp,cl
add eax,ebp
- call getcachesector
+ pm_call get_cache_block
pop bx
and bx,(SECTOR_SIZE >> 2)-1
shl bx,2
mov ebp,[gs:si+bx]
shl ebp,cl
add eax,ebp
- call getcachesector
+ pm_call get_cache_block
pop bx
and bx,(SECTOR_SIZE >> 2)-1
shl bx,2
%include "writestr.inc" ; String output
%include "writehex.inc" ; Hexadecimal output
%include "strecpy.inc" ; strcpy with end pointer check
-%include "cache.inc" ; Metadata disk cache
%include "localboot.inc" ; Disk-based local boot
; -----------------------------------------------------------------------------
;
; Initialize the metadata cache
;
- call initcache
+ mov eax, [ClustSize]
+ pm_call cache_init
;
; Now, everything is "up and running"... patch kaboom for more
.scansector:
; EAX <- directory sector to scan
- call getcachesector
+ pm_call get_cache_block
; GS:SI now points to this sector
mov cx,SECTOR_SIZE/32 ; 32 == directory entry size
cmp eax,0
jz .fail
.fetch_cache:
- call getcachesector
+ pm_call get_cache_block
.move_current:
add si,bx ; Resume last position in sector
mov ecx,SECTOR_SIZE ; 0 out high part
;
getfatsector:
add eax,[FAT] ; FAT starting address
- jmp getcachesector
+ pm_call get_cache_block
; -----------------------------------------------------------------------------
; Common modules
%include "plaincon.inc" ; writechr
%include "writestr.inc" ; String output
%include "writehex.inc" ; Hexadecimal output
-%include "cache.inc" ; Metadata disk cache
%include "localboot.inc" ; Disk-based local boot
; -----------------------------------------------------------------------------