/*
    Debug.c, Copyright  (c) by Lukas Ruf, lr@lpr.ch,
    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/IO/ia32/Debug.c,v $
	Author(s):             Lukas Ruf, lr@lpr.ch
	Affiliation:           ETH Zuerich, TIK
	Version:               $Revision: 3036 $
	Creation Date:         
	Last Date of Change:   $Date: 2007-06-01 02:25:06 +0200 (Fre, 01 Jun 2007) $      by: $Author: sryffel $
*/
#include "Support.h"
#include "Debug.h"
#include "SupportAsm.h"
#include "tm-include.h"
#include "System.h"

//-LR char DummyBuffer[128 * 1024];

//-CJ int xx_was_in_tmMain = 0;

void BRK()
{
  return;
}
void STP()
{
  asm("hlt");
}

void DisplayContext(char *ps, ProcContextPtr ctx)
{
  Debug("%s\n",ps);
  Debug("addr(ProcContext) = %p\n",ctx);
  Debug("SS0  %p  ESP0 %p  TSS  %p \n",
      ctx->proc_ss0, ctx->proc_esp0, ctx->cpu_tss);
  //-CJ  if (((unsigned int)ctx < 0x8000) || ((unsigned int)ctx > 0x80000)) {
  if (((unsigned int)ctx < KERNEL_VMA_BASE) )
  {
    Debug("Context Address looks strange to me: %p\n",ctx);
    asm(" movl %esp,%eax ; \
        movl $0x70000,%esp ; \
        //-LR           pushl %eax ; \
        //-LR           pushl %esp ; \
        //-LR           call DumpStack \
        ");  /* set exception stack */
    Debug(" Something went completely wrong :-( \n");
    asm(" hlt ");
  }
#ifndef DEBUG_W_CONTEXT
#define DEBUG_W_CONTEXT 1
#endif

#ifdef DEBUG_W_CONTEXT
  Debug("addr(StackFrame)  = %p\n",ctx->sf);
  Debug("EAX  %p  EBX  %p  ECX  %p  EDX  %p\n",
        ctx->sf->tf_eax, ctx->sf->tf_ebx, ctx->sf->tf_ecx, ctx->sf->tf_edx);
  Debug("CS   %p  DS   %p  ES   %p  FS   %p\n",
        ctx->sf->tf_cs , ctx->sf->tf_ds , ctx->sf->tf_es , ctx->sf->tf_fs );
  Debug("GS   %p  SS   %p  EIP  %p  EF   %p\n",
        ctx->sf->tf_gs , ctx->sf->tf_ss , ctx->sf->tf_eip, ctx->sf->tf_eflags);
  Debug("ESP  %p  EBP  %p  EDI  %p  ESI  %p\n",
        ctx->sf->tf_esp, ctx->sf->tf_ebp, ctx->sf->tf_edi, ctx->sf->tf_esi);
  Debug("tSP  %p  trp  %p  err  %p  CR3  %p\n",
        ctx->sf->tf_temp_esp, ctx->sf->tf_trapno, ctx->sf->tf_err, ctx->sf->tf_pdbr);
  Debug("last %p  priority %6i  schedFlags 0x%02x\n", 
        ctx->sf->tf_last, ctx->sf->tf_priority, ctx->sf->tf_schedFlags);
#endif

  // ERROR("DISPLAYCONTEXT");
  //-CJ    asm(" hlt ");
  return;
}

void DumpStack(unsigned int esp)
{
  unsigned int *stack = NULL;
  int i = 0;

  printf("Schedules: %8li, Restored: %8li, Interrupted: %8li\n",
         SysGetScheduled(), SysGetRestored(), SysGetInterrupted());

  printf("Local Stack: esp = %p\n", (void *)&esp);
  stack = (unsigned int*)&esp;
  for (i = 0; i < 15; i++)
    printf("0x%2x:%p ", i*4, (void*)stack[i]);

  printf("Stack Dump:  esp = %p\n", (void*)esp);
  stack = (unsigned int*)esp;
  for (i = 0; i < 30; i++)
    printf("0x%2x:%p ", i*4, (void*)stack[i]);

  printf("\n");
  DisplayContext("DumpStack", (ProcContextPtr)esp);
}



void DumpImpRegs(unsigned int ldtr_r, unsigned int tr_r, unsigned int fs_r, unsigned int gs_r, unsigned int ss_r, unsigned int ds_r, unsigned int es_r, unsigned int cs_r, unsigned int esp_r, unsigned int eip_r)
{
  printf("CS  %#x  DS %#x ES %#x SS %#x GS %#x FS %#x\n",
         cs_r, ds_r, es_r, ss_r, gs_r, fs_r);
  printf("ESP %#.8x EIP %#.8x TR %#o LDTR %#o\n", esp_r, eip_r, tr_r, ldtr_r);
  return;
}


void MyDumpStack(unsigned int *addr)
{
  int   i = 0;


  printf("MemDump @ %p\n", addr);
  printf("Address:   | Data\n===========================================\n");
  for(i = 0; i < 8; i++)
  {
    printf("%#10.8x | ", addr );
    printf("%#.8x %#.8x %#.8x %#.8x\n",
           *addr++, *addr++, *addr++, *addr++ );
  }
}
