⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winhpa48.cpp

📁 HPA就是host protect area
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   reg_cmd_info.lbaSize = LBA48;
   reg_cmd_info.lbaHigh = lbahi;
   reg_cmd_info.lbaLow = lbalo;

   // Execute the command.

   return exec_non_data_cmd( dev );
}


//*************************************************************
//
// sub_setup_command() -- setup the command parameters
//                        in FR, SC, SN, CL, CH and DH.
//
//*************************************************************

static void sub_setup_command( void )

{

   // output DevCtrl - same for all devices and commands
   pio_outbyte( CB_DC, reg_cmd_info.dc );

   // output command parameters
   if ( reg_cmd_info.lbaSize == LBA28 )
   {
      // in ATA LBA28 mode
      pio_outbyte( CB_FR, (unsigned char) reg_cmd_info.fr );
      pio_outbyte( CB_SC, (unsigned char) reg_cmd_info.sc );
      pio_outbyte( CB_SN, (unsigned char) reg_cmd_info.lbaLow );
      pio_outbyte( CB_CL, (unsigned char) ( reg_cmd_info.lbaLow >> 8 ) );
      pio_outbyte( CB_CH, (unsigned char) ( reg_cmd_info.lbaLow >> 16 ) );
      pio_outbyte( CB_DH, (unsigned char) ( ( reg_cmd_info.dh & 0xf0 )
                                            | ( ( reg_cmd_info.lbaLow >> 24 ) & 0x0f ) ) );
   }
   else
   if ( reg_cmd_info.lbaSize == LBA48 )
   {
      // in ATA LBA48 mode
      pio_outbyte( CB_FR, (unsigned char) ( reg_cmd_info.fr >> 8 ) );
      pio_outbyte( CB_SC, (unsigned char) ( reg_cmd_info.sc >> 8 ) );
      pio_outbyte( CB_SN, (unsigned char) ( reg_cmd_info.lbaLow >> 24 ) );
      pio_outbyte( CB_CL, (unsigned char) reg_cmd_info.lbaHigh );
      pio_outbyte( CB_CH, (unsigned char) ( reg_cmd_info.lbaHigh >> 8 ) );
      pio_outbyte( CB_FR, (unsigned char) reg_cmd_info.fr );
      pio_outbyte( CB_SC, (unsigned char) reg_cmd_info.sc );
      pio_outbyte( CB_SN, (unsigned char) reg_cmd_info.lbaLow );
      pio_outbyte( CB_CL, (unsigned char) ( reg_cmd_info.lbaLow >> 8 ) );
      pio_outbyte( CB_CH, (unsigned char) ( reg_cmd_info.lbaLow >> 16 ) );
      pio_outbyte( CB_DH, reg_cmd_info.dh  );
   }
   else
   {
      // for ATAPI PACKET command
      pio_outbyte( CB_FR, (unsigned char) reg_cmd_info.fr  );
      pio_outbyte( CB_SC, (unsigned char) reg_cmd_info.sc  );
      pio_outbyte( CB_SN, (unsigned char) reg_cmd_info.sn  );
      pio_outbyte( CB_CL, (unsigned char) reg_cmd_info.cl  );
      pio_outbyte( CB_CH, (unsigned char) reg_cmd_info.ch  );
      pio_outbyte( CB_DH, reg_cmd_info.dh  );
   }
}

//*************************************************************
//
// sub_trace_command() -- trace the end of a command.
//
//*************************************************************

static void sub_trace_command( void )

{
//	while(0x80 & pio_inbyte( CB_STAT ));
   reg_cmd_info.st = pio_inbyte( CB_STAT );
   reg_cmd_info.as = pio_inbyte( CB_ASTAT );
   reg_cmd_info.er = pio_inbyte( CB_ERR );

// !!! if you want to read back the other device registers
// !!! at the end of a command then this is the place to do
// !!! it. The code here is just and example of out this is
// !!! done on a little endian system like an x86.

#if 1    // read back other registers

   {
      unsigned long lbaHigh;
      unsigned long lbaLow;
      unsigned char sc48[2];
      unsigned char lba48[8];

      lbaHigh = 0;
      lbaLow = 0;
      if ( reg_cmd_info.lbaSize == LBA48 )
      {
         // read back ATA LBA48...
         sc48[0]  = pio_inbyte( CB_SC );
         lba48[0] = pio_inbyte( CB_SN );
         lba48[1] = pio_inbyte( CB_CL );
         lba48[2] = pio_inbyte( CB_CH );
         pio_outbyte( CB_DC, CB_DC_HOB );
         sc48[1]  = pio_inbyte( CB_SC );
         lba48[3] = pio_inbyte( CB_SN );
         lba48[4] = pio_inbyte( CB_CL );
         lba48[5] = pio_inbyte( CB_CH );
         lba48[6] = 0;
         lba48[7] = 0;
         reg_cmd_info.lbaHigh = * (unsigned long *) ( lba48 + 4 );
         reg_cmd_info.lbaLow  = * (unsigned long *) ( lba48 + 0 );
	  }
      else
      if ( reg_cmd_info.lbaSize == LBA28 )
      {
         // read back ATA LBA28
         lbaLow = pio_inbyte( CB_DH );
         lbaLow = lbaLow << 8;
         lbaLow = lbaLow | pio_inbyte( CB_CH );
         lbaLow = lbaLow << 8;
         lbaLow = lbaLow | pio_inbyte( CB_CL );
         lbaLow = lbaLow << 8;
         lbaLow = lbaLow | pio_inbyte( CB_SN );

      reg_cmd_info.lbaLow=lbaLow & 0x0fffffff;
      }
      else
      {
         // really no reason to read back for ATAPI
      }
   }

#endif   // read back other registers

}

//*************************************************************
//
// sub_select() - function used to select a drive.
//
// Function to select a drive making sure that BSY=0 and DRQ=0.
//
//**************************************************************

static int sub_select( unsigned char dev )

{
   unsigned char status;

   // PAY ATTENTION HERE
   // The caller may want to issue a command to a device that doesn't
   // exist (for example, Exec Dev Diag), so if we see this,
   // just select that device, skip all status checking and return.
   // We assume the caller knows what they are doing!

   if ( reg_config_info[dev] < REG_CONFIG_TYPE_ATA )
   {
      // select the device and return

      pio_outbyte( CB_DH, (unsigned char) ( dev ? CB_DH_DEV1 : CB_DH_DEV0 ) );
      DELAY400NS;
      return 0;
   }

   // The rest of this is the normal ATA stuff for device selection
   // and we don't expect the caller to be selecting a device that
   // does not exist.
   // We don't know which drive is currently selected but we should
   // wait BSY=0 and DRQ=0. Normally both BSY=0 and DRQ=0
   // unless something is very wrong!

   while ( 1 )
   {
      status = pio_inbyte( CB_STAT );
      if ( ( status & ( CB_STAT_BSY | CB_STAT_DRQ ) ) == 0 )
         break;
      if ( tmr_chk_timeout() )
      {
         reg_cmd_info.to = 1;
         reg_cmd_info.ec = 11;
         reg_cmd_info.st = status;
         reg_cmd_info.as = pio_inbyte( CB_ASTAT );
         reg_cmd_info.er = pio_inbyte( CB_ERR );
         return 1;
      }
   }

   // Here we select the drive we really want to work with by
   // setting the DEV bit in the Drive/Head register.

   pio_outbyte( CB_DH, (unsigned char) ( dev ? CB_DH_DEV1 : CB_DH_DEV0 ) );
   DELAY400NS;

   // Wait for the selected device to have BSY=0 and DRQ=0.
   // Normally the drive should be in this state unless
   // something is very wrong (or initial power up is still in
   // progress).

   while ( 1 )
   {
      status = pio_inbyte( CB_STAT );
      if ( ( status & ( CB_STAT_BSY | CB_STAT_DRQ ) ) == 0 )
         break;
      if ( tmr_chk_timeout() )
      {
         reg_cmd_info.to = 1;
         reg_cmd_info.ec = 12;
         reg_cmd_info.st = status;
         reg_cmd_info.as = pio_inbyte( CB_ASTAT );
         reg_cmd_info.er = pio_inbyte( CB_ERR );
         return 1;
      }
   }

   // All done.  The return values of this function are described in
   // ATAIO.H.

   if ( reg_cmd_info.ec )
      return 1;
   return 0;
}

//*************************************************************
//
// sub_wait_poll() - wait for interrupt or poll for BSY=0
//
//*************************************************************

static void sub_wait_poll( unsigned char we, unsigned char pe )

{
   unsigned char status;

   // Wait for interrupt -or- wait for not BUSY -or- wait for time out.

   if ( we && int_use_intr_flag )
   {
//      if ( SYSTEM_WAIT_INTR_OR_TIMEOUT() )    // time out ?
      {
         reg_cmd_info.to = 1;
         reg_cmd_info.ec = we;
      }
   }
   else
   {
      while ( 1 )
      {
         status = pio_inbyte( CB_ASTAT );       // poll for not busy
         if ( ( status & CB_STAT_BSY ) == 0 )
            break;
         if ( tmr_chk_timeout() )               // time out yet ?
         {
            reg_cmd_info.to = 1;
            reg_cmd_info.ec = pe;
            break;
         }
      }
   }
}

//***********************************************************
//
// functions used to read/write the BMIDE registers
//
//***********************************************************

static unsigned char pio_readBusMstrCmd( void )

{
   unsigned char x;

   if ( ! pio_bmide_base_addr )
      return 0;
   x = * (pio_bmide_base_addr + BM_COMMAND_REG );
   return x;
}


static unsigned char pio_readBusMstrStatus( void )

{
   unsigned char x;

   if ( ! pio_bmide_base_addr )
      return 0;
   x = * ( pio_bmide_base_addr + BM_STATUS_REG );
   return x;
}


static void pio_writeBusMstrCmd( unsigned char x )

{

   if ( ! pio_bmide_base_addr )
      return;
   * ( pio_bmide_base_addr + BM_COMMAND_REG ) = x;
}


static void pio_writeBusMstrStatus( unsigned char x )

{

   if ( ! pio_bmide_base_addr )
      return;
   * ( pio_bmide_base_addr + BM_STATUS_REG ) =  x;
}

//*************************************************************
//
// These functions do basic IN/OUT of byte and word values:
//
//    pio_inbyte()
//    pio_outbyte()
//    pio_inword()
//    pio_outword()
//
//*************************************************************

static unsigned char pio_inbyte( unsigned char addr )

{
  DWORD dwPortVal;
  //!!! read an 8-bit ATA register
//   return * pio_reg_addrs[ addr ];
 GetPortVal(pio_reg_addrs[ addr ] , &dwPortVal, 1);
   return (unsigned char)dwPortVal;
}

//*************************************************************

static void pio_outbyte( int addr, unsigned char data )

{

   //!!! write an 8-bit ATA register
//   * pio_reg_addrs[ addr ] = data;

//   outportb( pio_reg_addrs[ addr ] , data);
	 SetPortVal(pio_reg_addrs[ addr ], data, 1);
}

//*************************************************************

static unsigned int pio_inword( unsigned char addr )

{
	DWORD dwPortVal;
   //!!! read an 8-bit ATA register (usually the ATA Data register)
   //return * ( (unsigned int *) pio_reg_addrs[ addr ] );

//   return inport ( pio_reg_addrs[ addr ] );
 GetPortVal(pio_reg_addrs[ addr ] , &dwPortVal, 2);
   return dwPortVal;

}

//*************************************************************

static void pio_outword( int addr, unsigned int data )

{

   //!!! Write an 8-bit ATA register (usually the ATA Data register)
   //* ( (unsigned int *) pio_reg_addrs[ addr ] ) = data;

   //outport ( pio_reg_addrs[ addr ] , data);
	 SetPortVal(pio_reg_addrs[ addr ], data, 2);
}

//*************************************************************

static unsigned long pio_indword( unsigned char addr )

{
	DWORD dwPortVal;
   //!!! read an 8-bit ATA register (usually the ATA Data register)

 //  return * ( (unsigned long *) pio_reg_addrs[ addr ] );
 GetPortVal(pio_reg_addrs[ addr ] , &dwPortVal, 4);
   return dwPortVal;
}

//*************************************************************

static void pio_outdword( int addr, unsigned long data )

{

   //!!! Write an 8-bit ATA register (usually the ATA Data register)

   //* ( (unsigned long *) pio_reg_addrs[ addr ] ) = data;
	 SetPortVal(pio_reg_addrs[ addr ], data, 4);
}

//*************************************************************
//
// Command timing functions
//
//**************************************************************


//static long tmr_cmd_start_time;      // command start time - see the
                              // tmr_set_timeout() and
                              // tmr_chk_timeout() functions.

//*************************************************************
//
// tmr_set_timeout() - get the command start time
//
//**************************************************************

static void tmr_set_timeout( void )

{

   // get the command start time
   tmr_cmd_start_time = 0;//SYSTEM_READ_TIMER();
}

//*************************************************************
//
// tmr_chk_timeout() - check for command timeout.
//
// Gives non-zero return if command has timed out.
//
//**************************************************************

static int tmr_chk_timeout( void )

{
   long curTime;

   // get current time
   curTime = 0;//SYSTEM_READ_TIMER();

   // timed out yet ?
   if ( curTime >= ( tmr_cmd_start_time
                     + ( TMR_TIME_OUT * SYSTEM_TIMER_TICKS_PER_SECOND ) ) )
      return 1;      // yes

   // no timeout yet
   return 0;
}

// end testhpa.c
//

// test code:
void main()
{int st,st1;unsigned long lbalo=0xfff,lbahi=0;
st=reg_reset(0);
st1=reg_config();

  bool bResult;

  // Call InitializeWinIo to initialize the WinIo library.

  bResult = InitializeWinIo();

  if (bResult)
  {
//int reg_non_data_lba48( unsigned char dev, unsigned char cmd,
//                        unsigned int fr, unsigned int sc,
//                        unsigned long lbahi, unsigned long lbalo )
	printf("In the harddisk there are number of block: \n");
tt:
st=reg_non_data_lba48(0, READ_NATIVE_MAX_ADDRESS_EXT, 0, 0, lbahi, lbalo);
printf("%d,%d,%lx,%ld\n",st, st1,reg_cmd_info.lbaLow, reg_cmd_info.lbaLow);
printf("STAT=%x,ASTAT=%x,ERR=%x,\n\n",reg_cmd_info.st, reg_cmd_info.as, reg_cmd_info.er);
if (reg_cmd_info.st!=0x50) goto tt;
//	printf("Please input HPA block number:");
//	scanf("%ld",&lbalo);
lbalo=reg_cmd_info.lbaLow;//-lbalo;
st=reg_non_data_lba48(0,SET_MAX_ADDRESS_EXT,0,0, lbahi,lbalo);
printf("%d,%d,%lx,%ld\n",st, st1,reg_cmd_info.lbaLow,lbalo);
printf("STAT=%x,ASTAT=%x,ERR=%x,\n\n",reg_cmd_info.st, reg_cmd_info.as, reg_cmd_info.er);

st=reg_non_data_lba48(0,READ_NATIVE_MAX_ADDRESS_EXT,0,0,lbahi, lbalo);
printf("%d,%d,%lx,%ld\n",st, st1,reg_cmd_info.lbaLow, reg_cmd_info.lbaLow);
printf("STAT=%x,ASTAT=%x,ERR=%x,\n\n",reg_cmd_info.st, reg_cmd_info.as, reg_cmd_info.er);


    // When you're done using WinIo, call ShutdownWinIo

    ShutdownWinIo();

	printf("Press any key to continue...");
	st=getchar();
  }
  else
  {
    printf("Error during initialization of WinIo.\n");
    exit(1);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -