Subversion Repositories shark

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Project: S.Ha.R.K.
 *
 * Coordinators:
 *   Giorgio Buttazzo    <giorgio@sssup.it>
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *
 * Authors     :
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *   (see the web pages for full authors list)
 *
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
 *
 * http://www.sssup.it
 * http://retis.sssup.it
 * http://shark.sssup.it
 */


/**
 ------------
 CVS :        $Id: oldmem.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $

 File:        $File$
 Revision:    $Revision: 1.1.1.1 $
 Last update: $Date: 2002-03-29 14:12:52 $
 ------------

 Basic Memory Manager Functions:
 A classic fixed partition allocator!

 This file comes from the Hartik 3.3.0's vm-mem.c

**/


/*
 * Copyright (C) 2000 Paolo Gai
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */



#include <kernel/kern.h>

#define MAX_PARTITION   50 /* Max available partition */

static struct {
        BYTE used;
        BYTE *addr;
        DWORD size;
} mem_table[MAX_PARTITION];

void kern_mem_init(struct multiboot_info *multiboot)
{
  register int i;    /* a counter    */
  DWORD size;        /* Memory size  */
  BYTE *base;        /* base address */
  LIN_ADDR b;        /* base address */

  /* Get info about extended memory! We suppose that X has loaded */
  /* there the application; if you switch to DOS memory, then you */
  /* have to change the stuff in order it works; check X_...  for */
  /* details.                                                     */
  X_meminfo(&b,&size,NULL,NULL);
  base = (BYTE *)b;
  #ifdef __MEM_DEBUG__
    message("PM Free Mem Base         : %lx\n",base);
    message("PM null addr (0L)        : %lx\n",appl2linear((void *)0L));
    message("PM Free Mem Base (Cnvrtd): %lp\n",base);
  #endif

  mem_table[0].used = 1;
  mem_table[0].addr = base;
  mem_table[0].size = size;
  for (i = 1; i < MAX_PARTITION; i++) mem_table[i].used = 0;

  #ifdef __MEM_DEBUG__
    kern_mem_dump();
  #endif
}

void *kern_alloc(DWORD s)
{
    void *p = NULL;
    int i = 0;

    while (i < MAX_PARTITION && p == NULL) {
        if (mem_table[i].used && (mem_table[i].size >= s))
                p = mem_table[i].addr;
        else i++;
    }
    if (p != NULL) {
        if (mem_table[i].size > s) {
            mem_table[i].size -= s;
            mem_table[i].addr += s;
        }
        else mem_table[i].used = FALSE;
    }
    return(p);
}

WORD kern_free(void *p,DWORD s)
{
    register int i = 1;
    unsigned i1 = 0, i2 = 0;

    while (i < MAX_PARTITION && ((i1 == 0) || (i2 == 0)) ) {
        if (mem_table[i].used) {
            if (mem_table[i].addr + mem_table[i].size == p) i1 = i;
            if (mem_table[i].addr == (BYTE *)(p) + s) i2 = i;
        }
        i++;
    }
    if (i1 != 0 && i2 != 0) {
        mem_table[i1].size += mem_table[i2].size + s;
        mem_table[i2].used = FALSE;
    }
    else if (i1 == 0 && i2 != 0) {
        mem_table[i2].addr = p;
        mem_table[i2].size += s;
    }
    else if (i1 != 0 && i2 == 0) mem_table[i1].size += s;
    else {
        i = 0;
        while (i < MAX_PARTITION && (mem_table[i].used == TRUE)) i++;
        if (i == MAX_PARTITION) return(FALSE);
        mem_table[i].addr = p;
        mem_table[i].size = s;
        mem_table[i].used = TRUE;
    }
    return(TRUE);
}

void kern_mem_dump(void)
{
    register int i;
    for (i = 0; i < MAX_PARTITION; i++) {
        if (mem_table[i].used) message("Entry : [%d] Addr : %p Size : %ld\n",i,mem_table[i].addr,mem_table[i].size);
    }
}