/*
    MMDirectMapping.c, Copyright  (c) by George Fankhauser,
    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.
*/
/*
 
*/

#include "MMMapping.h"
#include "Threads.h"
#include "Support.h"

#include "Unix.h"


unsigned int physBase = 0;
unsigned int bootStackBottom = 0;

Error   mmInitMemoryMapping(Address codeAddr, unsigned long int codeSize,
                            Address dataAddr, unsigned long int dataSize,
                            Address userLoadedInKernelAt)
{
#ifdef __svr4__

  stack_t ss;

  ss.ss_sp = (char*)(physBase + BOOTSTACKTOP); // setup exception stack
  ss.ss_size = BOOTSTACKSIZE;                 // size
  ss.ss_flags = 0;          			// currently not on this stack
  sigaltstack(&ss, NULL);

#elif linux


#else // BSD like

  struct sigstack ss;

  ss.ss_sp = (char*)(physBase + BOOTSTACKTOP); // setup exception stack
  ss.ss_onstack = FALSE;                 // currently not on this stack
  sigstack(&ss, NULL);

#endif

  return MM_INITMEMORYMAPPINGOK;
}

Error mmMapPages(Page startPage, Page nOfPages, PageStatus pstat)
{
  return MM_MAPPAGESOK;
}


Error mmUnmapPages(Page startPage, Page nOfPages)
{
  return MM_UNMAPPAGESOK;
}


Error mmMovePage(Page from, Page to)
{
  /* direct mapped memory systems can only copy the page */
  byteCopy((Address)(to*LOGICALPAGESIZE), (Address)(from*LOGICALPAGESIZE),
           LOGICALPAGESIZE);
  zeroOut((Address)(from*LOGICALPAGESIZE), LOGICALPAGESIZE);
  return MM_MOVEPAGEOK;
}


Error mmProtectPage(Page page, ProtectionMode pmode)
{
  /* direct mapped memory does nothing */
  return MM_PROTECTPAGEFAILED;
}


Error  mmAddressSpaceRange(AddressSpace space, Address* addressPtr,
                           unsigned long int* sizePtr)
{
  if (space == KERNEL)
  {
    *addressPtr = (Address)physBase;
    *sizePtr = (PHYSMEM-USERMEM);
  }
  else if (space == USER)
  {
    *addressPtr = (Address)physBase + (PHYSMEM-USERMEM);
    *sizePtr = USERMEM;
  }
  else
    return MM_ADDRESSSPACERANGEFAILED;
  return MM_ADDRESSSPACERANGEOK;
}
