# Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.61 $
+# $Revision: 1.62 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
 
 /*
  * Boot information structure, passed to kernel Main() routine
  * Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.4 $
+ * $Revision: 1.5 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
 
 /*
  * Misc. kernel definitions
  * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.6 $
+ * $Revision: 1.7 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
 
 struct vmm_io_map;
 struct emulation_state;
 
-
+/*Zheng 07/30/2008*/
 struct vm_ctrl_ops {
   int (*raise_irq)(struct guest_info * info, int irq);
+  int (*lower_irq)(struct guest_info * info, int irq);
 };
 
 
 
 
-
 typedef enum {SHADOW_PAGING, NESTED_PAGING} vmm_paging_mode_t;
 typedef enum {VM_RUNNING, VM_STOPPED, VM_SUSPENDED, VM_ERROR, VM_EMULATING} vm_operating_mode_t;
 
 
 
 int v3_raise_irq(struct guest_info * info, int irq);
 
+/*Zheng 07/30/2008*/
+int v3_lower_irq(struct guest_info * info, int irq);
+
+
+/*Zheng 07/30/2008*/
 
 struct intr_ctrl_ops {
   int (*intr_pending)(void * private_data);
   int (*get_intr_number)(void * private_data);
   int (*raise_intr)(void * private_data, int irq);
+  int (*lower_intr)(void * private_data, int irq);
   int (*begin_irq)(void * private_data, int irq);
 };
 
 
 #define PrintDebug(fmt, args...)
 #endif
 
+#ifdef DEBUG_RAMDISK
+#define Ramdisk_Print_Pic(_f, _a...) PrintTrace("\n8259a.c(%d) "_f, __LINE__, ## _a)
+#else
+#define Ramdisk_Print_Pic(_f, _a...)
+#endif
+
+
 typedef enum {RESET, ICW1, ICW2, ICW3, ICW4,  READY} pic_state_t;
 
 static const uint_t MASTER_PORT1 = 0x20;
   return 0;
 }
 
+
+/*Zheng 07/30/2008*/
+
+static int pic_lower_intr(void *private_data, int irq_no) {
+
+  struct pic_internal *state = (struct pic_internal*)private_data;
+
+  Ramdisk_Print_Pic("[pic_lower_intr] IRQ line %d now low\n", (unsigned) irq_no);
+  if (irq_no <= 7) {
+
+    state->master_irr &= ~(1 << irq_no);
+    if ((state->master_irr & ~(state->master_imr)) == 0) {
+      Ramdisk_Print_Pic("\t\tFIXME: Master maybe should do sth\n");
+    }
+  } else if ((irq_no > 7) && (irq_no <= 15)) {
+
+    state->slave_irr &= ~(1 << (irq_no - 8));
+    if ((state->slave_irr & (~(state->slave_imr))) == 0) {
+      Ramdisk_Print_Pic("\t\tFIXME: Slave maybe should do sth\n");
+    }
+  }
+  return 0;
+}
+
+
+
 static int pic_intr_pending(void * private_data) {
   struct pic_internal * state = (struct pic_internal*)private_data;
 
 }
 */
 
+
+/*Zheng 07/30/2008*/
 static struct intr_ctrl_ops intr_ops = {
   .intr_pending = pic_intr_pending,
   .get_intr_number = pic_get_intr_number,
   .raise_intr = pic_raise_intr,
   .begin_irq = pic_begin_irq,
+  .lower_intr = pic_lower_intr, //Zheng added
+
 };
 
 
 
 
 
   
-    
+#ifdef RAMDISK_BOOT
+#include <devices/ramdisk.h>
+//ramdisk_state
+static struct ramdisk_t *ramdisk_state;
+#endif    
 
 
 
   
   PrintDebug(" to port 0x%x ... ", port);
 
+#ifdef RAMDISK_BOOT
+
+  uint_t err;
+
+  if (((port >= 0x170 && port <= 0x177) || port == 0x376 || port == 0x377)
+      && (dev->vm->cpu_mode == REAL)) {
+
+    
+    err = ramdisk_state->eops.write_port(port, src, length, dev);
+
+  }else{
+#endif
+
   switch (length) {
   case 1:
     Out_Byte(port,((uchar_t*)src)[0]);
     for (i = 0; i < length; i++) { 
       Out_Byte(port, ((uchar_t*)src)[i]);
     }
-  }
-
+  } //switch length
+#ifdef RAMDISK_BOOT
+  }//else not ramdisk
+#endif
   PrintDebug(" done\n");
   
   return length;
 
   PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port);
 
-  switch (length) {
-  case 1:
-    ((uchar_t*)src)[0] = In_Byte(port);
-    break;
-  case 2:
-    ((ushort_t*)src)[0] = In_Word(port);
-    break;
-  case 4:
-    ((uint_t*)src)[0] = In_DWord(port);
-    break;
-  default:
-    for (i = 0; i < length; i++) { 
-      ((uchar_t*)src)[i] = In_Byte(port);
-    }
-  }
+#ifdef RAMDISK_BOOT
+
+  uint_t err;
+
+  if (((port >= 0x170 && port <= 0x177) || port == 0x376 || port == 0x377)
+      && (dev->vm->cpu_mode == REAL)) {
+
+    err = ramdisk_state->eops.read_port(port, src, length, dev);
+
+  }else{
+#endif
+
+    switch (length) {
+    case 1:
+      ((uchar_t*)src)[0] = In_Byte(port);
+      break;
+    case 2:
+      ((ushort_t*)src)[0] = In_Word(port);
+      break;
+    case 4:
+      ((uint_t*)src)[0] = In_DWord(port);
+      break;
+    default:
+      for (i = 0; i < length; i++) { 
+       ((uchar_t*)src)[i] = In_Byte(port);
+      }
+    }//switch length
+#ifdef RAMDISK_BOOT
+  }//else not ramdisk
+#endif
 
   PrintDebug(" done ... read 0x");
 
   PrintDebug(" to port 0x%x ... ", port);
 
   PrintDebug(" ignored\n");
-  
+ 
+#ifdef RAMDISK_BOOT
+
+  uint_t err;
+
+  if (((port >= 0x3e8 && port <= 0x3ef) || 
+       (port >= 0x2e8 && port <= 0x2ef))
+      && (dev->vm->cpu_mode == REAL)) {
+
+    err = ramdisk_state->eops.write_port_ignore(port, src, length, dev);
+  }
+#endif
+ 
   return length;
 }
 
   memset((char*)src,0,length);
   PrintDebug(" ignored (return zeroed buffer)\n");
 
+#ifdef RAMDISK_BOOT
+
+  uint_t err;
+
+  if (((port >= 0x3e8 && port <= 0x3ef) || 
+       (port >= 0x2e8 && port <= 0x2ef))
+      && (dev->vm->cpu_mode == REAL)) {
+
+    err = ramdisk_state->eops.read_port_ignore(port, src, length, dev);
+  }
+#endif
+
   return length;
 }
 
 
   }
 
+#ifdef RAMDISK_BOOT
+
+  ramdisk_state->cops.init(ramdisk_state, dev);
+
+#endif
+
   return 0;
 }
 
 
   PrintDebug("generic: deinit_device\n");
 
+#ifdef RAMDISK_BOOT
+
+  ramdisk_state->cops.close(ramdisk_state);
+  
+#endif
+
   for (i = 0; i < state->num_irq_ranges; i++) { 
     PrintDebug("generic: unhooking irqs 0x%x to 0x%x\n", state->irq_ranges[i][0], state->irq_ranges[i][1]);
 
     generic_state->irq_ranges = NULL;
   }
 
+#ifdef RAMDISK_BOOT
+
+  ramdisk_state = create_ramdisk();
+  V3_ASSERT(ramdisk_state != NULL);
+
+#endif
 
   struct vm_device *device = create_device("GENERIC", &dev_ops, generic_state);
 
 
 ; Definitions for use in GeekOS boot code
 ; Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
-; $Revision: 1.9 $
+; $Revision: 1.10 $
 
 ; This is free software.  You are permitted to use,
 ; redistribute, and modify it as specified in the file "COPYING".
 
  * Physical memory allocation
  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
- * $Revision: 1.10 $
+ * $Revision: 1.11 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
 
 ; -*- fundamental -*-
 ; GeekOS setup code
 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
-; $Revision: 1.5 $
+; $Revision: 1.6 $
 
 ; This is free software.  You are permitted to use,
 ; redistribute, and modify it as specified in the file "COPYING".
 
       {0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE}, // PCI Config Data
 #endif
  
-#if 0
+#if 1
 
       // Monitor the IDE controllers (very slow)
 
 
 #define PrintDebug(fmt, args...)
 #endif
 
+#ifdef DEBUG_RAMDISK
+#define Ramdisk_Print_Intr(_f, _a...) PrintTrace("\nvmm_intr.c(%d) "_f, __LINE__, ## _a)
+#else
+#define Ramdisk_Print_Intr(_f, _a...)
+#endif
+
+/*Zheng 07/30/2008*/
 void init_interrupt_state(struct guest_info * info) {
   info->intr_state.excp_pending = 0;
   info->intr_state.excp_num = 0;
   info->intr_state.excp_error_code = 0;
 
   info->vm_ops.raise_irq = &v3_raise_irq;
+  info->vm_ops.lower_irq = &v3_lower_irq; //Zheng added
 }
 
 void set_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state) {
   struct guest_info *guest = (struct guest_info *)(state->opaque);
 
   PrintDebug("guest_irq_injection: injecting irq 0x%x into guest 0x%x\n",state->irq,guest);
+  Ramdisk_Print_Intr("[guest_injection_irq_handler] raise_irq = %x\n", state->irq);
   guest->vm_ops.raise_irq(guest,state->irq);
 }
 
     intr_state->excp_error_code = error_code;
     intr_state->excp_error_code_valid = 1;
     PrintDebug("Raising exception with error code: %x\n", error_code);
+    Ramdisk_Print_Intr("[v3_raise_exception_with_error] error code: %x\n", error_code);
   } else {
     PrintError("exception already pending, currently not implemented\n");
+    Ramdisk_Print_Intr("[v3_raise_exception_with_error] not implemented\n");
     return -1;
   }
 
 
 int v3_raise_exception(struct guest_info * info, uint_t excp) {
   struct vm_intr * intr_state = &(info->intr_state);
-
+  Ramdisk_Print_Intr("[v3_raise_exception]\n");
   if (intr_state->excp_pending == 0) {
     intr_state->excp_pending = 1;
     intr_state->excp_num = excp;
   return 0;
 }
 
+/*Zheng 07/30/2008*/
+
+int v3_lower_irq(struct guest_info * info, int irq) {
+  // Look up PIC and resend
+  V3_ASSERT(info);
+  V3_ASSERT(info->intr_state.controller);
+  V3_ASSERT(info->intr_state.controller->raise_intr);
+
+  Ramdisk_Print_Intr("[v3_lower_irq]\n");
+
+  //  if ((info->intr_state.controller) && 
+  //  (info->intr_state.controller->raise_intr)) {
+    info->intr_state.controller->lower_intr(info->intr_state.controller_state, irq);
+    //} else {
+    // PrintDebug("There is no registered Interrupt Controller... (NULL POINTER)\n");
+    // return -1;
+    //}
+  return 0;
+}
 
 int v3_raise_irq(struct guest_info * info, int irq) {
   // Look up PIC and resend
   V3_ASSERT(info->intr_state.controller);
   V3_ASSERT(info->intr_state.controller->raise_intr);
 
+  Ramdisk_Print_Intr("[v3_raise_irq]\n");
+
   //  if ((info->intr_state.controller) && 
   //  (info->intr_state.controller->raise_intr)) {
     info->intr_state.controller->raise_intr(info->intr_state.controller_state, irq);
   return 0;
 }
 
-
+ 
 
 int intr_pending(struct guest_info * info) {
   struct vm_intr * intr_state = &(info->intr_state);
 
+  //  Ramdisk_Print_Intr("[intr_pending]\n");
   if (intr_state->excp_pending == 1) {
     return 1;
   } else if (intr_state->controller->intr_pending(intr_state->controller_state) == 1) {
   if (intr_state->excp_pending == 1) {
     return intr_state->excp_num;
   } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
+    Ramdisk_Print_Intr("[get_intr_number] intr_number = %d\n", intr_state->controller->get_intr_number(intr_state->controller_state));
     return intr_state->controller->get_intr_number(intr_state->controller_state);
   }
 
  struct vm_intr * intr_state = &(info->intr_state);
 
   if (intr_state->excp_pending) {
+    Ramdisk_Print_Intr("[get_intr_type] Exception\n");
     return EXCEPTION;
   } else if (intr_state->controller->intr_pending(intr_state->controller_state)) {
+    Ramdisk_Print_Intr("[get_intr_type] External_irq\n");
     return EXTERNAL_IRQ;
   }
-
+    Ramdisk_Print_Intr("[get_intr_type] Invalid_Intr\n");
   return INVALID_INTR;
 }
 
   struct vm_intr * intr_state = &(info->intr_state);
 
   if (type == EXCEPTION) {
-
+    Ramdisk_Print_Intr("[injecting_intr] Exception\n");
     intr_state->excp_pending = 0;
     intr_state->excp_num = 0;
     intr_state->excp_error_code = 0;
     intr_state->excp_error_code_valid = 0;
     
   } else if (type == EXTERNAL_IRQ) {
+    Ramdisk_Print_Intr("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);
     return intr_state->controller->begin_irq(intr_state->controller_state, intr_num);
   }
 
 
 //  -*- fundamental -*-
 /////////////////////////////////////////////////////////////////////////
-// $Id: rombios.c,v 1.13 2008/08/14 18:22:45 cuizheng Exp $
+// $Id: rombios.c,v 1.14 2008/08/14 18:25:48 cuizheng Exp $
 /////////////////////////////////////////////////////////////////////////
 //
 //  Copyright (C) 2002  MandrakeSoft S.A.
 
 #endif // BX_ELTORITO_BOOT
 
-static char bios_cvs_version_string[] = "$Revision: 1.13 $";
-static char bios_date_string[] = "$Date: 2008/08/14 18:22:45 $";
+static char bios_cvs_version_string[] = "$Revision: 1.14 $";
+static char bios_date_string[] = "$Date: 2008/08/14 18:25:48 $";
 
-static char CVSID[] = "$Id: rombios.c,v 1.13 2008/08/14 18:22:45 cuizheng Exp $";
+static char CVSID[] = "$Id: rombios.c,v 1.14 2008/08/14 18:25:48 cuizheng Exp $";
 
 /* Offset to skip the CVS $Id: prefix */ 
 #define bios_version_string  (CVSID + 4)