/*
    Copyright 2001 (c) by Claudio Jeker,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/VMemory/sa1100/Attic/vm_bootup_hal.c,v $
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $  by: $Author: baderma $
 
*/
#include "vm.h"
#include "tt.h"						// ixp asm hal functions for PMap Layer
#include "vm_bootup.h"
#include "MemoryLayout.h"


struct topsyheader
{
  char		name[16];
  uint64	textstart;
  uint64	textsize;
  uint64	datastart;
  uint64	datasize;
  uint64	bssstart;
  uint64	bsssize;
  uint64	optsegment;
  uint64	optsegmentsize;
};

extern void __segmap(void);


void vm_MMU_or_HELL(struct vm_pmap *vm_pmap)
{
  /* set base address of TT1 in CP15 */
  printf("now setting TT1-Base!\n");
  setTTBase(vm_pmap->tt1base_p);
  /* TLB needs to be flushed each time before MMU is enabled or disabled! */
  printf("now flushing TLB!\n");
  flush_tlb();

  //-BL printf("dumping meory at TT1 base + 3070 * 4:\n");
  //-BL dumpMemory(vm_pmap->tt1base_p + (3070 * 4),0,128);
  //-BL printf("dumping meory at TT2 (1):\n");
  //-BL dumpMemory(0xc0248c00,0,1024);

  printf("now enabling MMU!\n");
  led(0x00);
  enableMMU();
  led(0x66);
  return;
}


int vm_get_physmap(struct vm_physmap **p)
{
  *p = (struct vm_physmap*)(address_t)BOOTSTACKBOTTOM;
  (*p)[0].start = PAGENUMBER(DRAM_BASE);
  (*p)[0].end = PAGENUMBER(DRAM_BASE + DRAM_AVAIL);

  /* until now there are no more memory banks.
  	 NOTE: normaly the available memory should be tested
  	 dynamically.
   */

  return 1; /* only one entry in physmap */

}

struct vm_segmap* vm_get_segmap(struct vm_physmap* physmap, int physcnt)
{
  struct vm_segmap* s;
  struct topsyheader* topsyheader;
  address_t hint;

  topsyheader = (struct topsyheader*)__segmap;

  s = (struct vm_segmap*)(physmap + physcnt);
  /* segmap starts right after the physmap */

  s->physmap = physmap;
  s->physcnt = physcnt;
  /* now we need to extract the other values form the kernel image header */
  s->text = (address_t)(unsigned long)topsyheader->textstart;
  s->textsize = topsyheader->textsize;
  hint = s->text + s->textsize;

  s->data = (address_t)(unsigned long)topsyheader->datastart;
  s->datasize = topsyheader->datasize;

  if ( hint < s->data + s->datasize )
    hint = s->data + s->datasize;

  s->bss = (address_t)(unsigned long)topsyheader->bssstart;
  s->bsssize = topsyheader->bsssize;

  if ( hint < s->bss + s->bsssize )
    hint = s->bss + s->bsssize;

  s->bootstackbottom = (address_t)BOOTSTACKBOTTOM;
  s->bootstacksize = BOOTSTACKSIZE;

  if ( hint < s->bootstackbottom + s->bootstacksize )
    hint = s->bootstackbottom + s->bootstacksize;

  s->optsegment = (address_t)(unsigned long)topsyheader->optsegment;
  s->optsegmentsize = topsyheader->optsegmentsize;
  s->bootalloccnt = 1;
  s->bootalloc[0].phys = PAGETOADDR(PAGENUMBER(hint + PAGESIZE));
  s->bootalloc[0].size = 0;

  vm_print_segmap(s);
  return s;
}
