OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [cmds/] [atabug.c] - Diff between revs 175 and 406

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 175 Rev 406
/*
/*
    atabug.c -- ATA debugging
    atabug.c -- ATA debugging
    Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
    Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
 
    This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
    This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
 
    This program is free software; you can redistribute it and/or modify
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version
    (at your option) any later version
 
 
    This program is distributed in the hope that it will be useful,
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    GNU General Public License for more details.
 
 
    You should have received a copy of the GNU General Public License
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
 
 
 
 
#include "support.h"
#include "support.h"
#include "common.h"
#include "common.h"
#include "atabug.h"
#include "atabug.h"
#include "ata.h"
#include "ata.h"
 
 
#include <ctype.h>
#include <ctype.h>
 
 
static int ata_num_commands;
static int ata_num_commands;
static command_struct ata_command[MAX_ATA_COMMANDS];
static command_struct ata_command[MAX_ATA_COMMANDS];
 
 
/* inode struct for ata */
/* inode struct for ata */
static struct inode _inode;
static struct inode _inode;
static struct inode *inode = &_inode;
static struct inode *inode = &_inode;
 
 
/* file struct for ata */
/* file struct for ata */
static struct file _filp;
static struct file _filp;
static struct file *filp = &_filp;
static struct file *filp = &_filp;
 
 
/* buffer for ata-data */
/* buffer for ata-data */
static unsigned char buf[512];
static unsigned char buf[512];
 
 
 
 
/**********************************************************************/
/**********************************************************************/
/*                                                                    */
/*                                                                    */
/*      A T A B U G                                                   */
/*      A T A B U G                                                   */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
/**********************************************************************/
/*
/*
        A T A _ I N I T
        A T A _ I N I T
 
 
        initializes the ATA core, and registers it with ORPmon
        initializes the ATA core, and registers it with ORPmon
*/
*/
void module_ata_init (void)
void module_ata_init(void)
{
{
  ata_num_commands = 0;
        ata_num_commands = 0;
 
 
  register_command ("atabug", "", "ATA debugger. Type 'atabug help' for help", atabug);
        register_command("atabug", "",
 
                         "ATA debugger. Type 'atabug help' for help", atabug);
 
 
  register_ata_command ("help", "", "Display this help message", atabug_help);
        register_ata_command("help", "", "Display this help message",
  register_ata_command ("exit", "", "Exit atabug and return to ORPmon", atabug_exit);
                             atabug_help);
  register_ata_command ("open", "<device> [<mode>]", "Opens the requested device. Device=<0|1>, Mode=<r>eadonly|read<w>rite.", ata_open_cmd);
        register_ata_command("exit", "", "Exit atabug and return to ORPmon",
 
                             atabug_exit);
 
        register_ata_command("open", "<device> [<mode>]",
 
                             "Opens the requested device. Device=<0|1>, Mode=<r>eadonly|read<w>rite.",
 
                             ata_open_cmd);
  register_ata_command ("close", "", "Closes the device.", ata_close_cmd);
  register_ata_command ("close", "", "Closes the device.", ata_close_cmd);
  register_ata_command ("reset", "<mode>", "Reset ata device(s).", ata_reset_cmd);
        register_ata_command("reset", "<mode>", "Reset ata device(s).",
  register_ata_command ("enable", "", "Enables ATA host controller, clears all resets", ata_enable_cmd);
                             ata_reset_cmd);
  register_ata_command ("dump_dev_regs", "", "Dump the (readable) ata device registers.", ata_dump_device_regs_cmd);
        register_ata_command("enable", "",
  register_ata_command ("dump_host_regs", "", "Dump the ata host registers.", ata_dump_host_regs_cmd);
                             "Enables ATA host controller, clears all resets",
  register_ata_command ("exec_cmd", "<cmd>", "Execute ata command <cmd> (hex)", ata_exec_cmd_cmd);
                             ata_enable_cmd);
  register_ata_command ("identify_device", "", "Dumps device's IDENTIFY DEVICE block.", ata_identify_device_cmd);
        register_ata_command("dump_dev_regs", "",
  register_ata_command ("program_timing", "<PIO mode>", "Programs the device to the selected PIO mode.", ata_set_piomode_cmd);
                             "Dump the (readable) ata device registers.",
  register_ata_command ("read_sectors", "<startsector> [<sectorcount>]", "Reads sector", ata_read_sectors_cmd);
                             ata_dump_device_regs_cmd);
  register_ata_command ("read_mbr", "<partition>", "Reads the Master Boot Record.", ata_read_mbr_cmd);
        register_ata_command("dump_host_regs", "",
  register_ata_command ("read_dosboot", "<sector>", "Reads the device's bootsector (FAT).", ata_read_dosboot_cmd);
                             "Dump the ata host registers.",
  register_ata_command ("select_device", "<device_no>", "Select ata device. device_no=<0|1>", ata_select_device_cmd);
                             ata_dump_host_regs_cmd);
 
        register_ata_command("exec_cmd", "<cmd>",
 
                             "Execute ata command <cmd> (hex)",
 
                             ata_exec_cmd_cmd);
 
        register_ata_command("identify_device", "",
 
                             "Dumps device's IDENTIFY DEVICE block.",
 
                             ata_identify_device_cmd);
 
        register_ata_command("program_timing", "<PIO mode>",
 
                             "Programs the device to the selected PIO mode.",
 
                             ata_set_piomode_cmd);
 
        register_ata_command("read_sectors", "<startsector> [<sectorcount>]",
 
                             "Reads sector", ata_read_sectors_cmd);
 
        register_ata_command("read_mbr", "<partition>",
 
                             "Reads the Master Boot Record.", ata_read_mbr_cmd);
 
        register_ata_command("read_dosboot", "<sector>",
 
                             "Reads the device's bootsector (FAT).",
 
                             ata_read_dosboot_cmd);
 
        register_ata_command("select_device", "<device_no>",
 
                             "Select ata device. device_no=<0|1>",
 
                             ata_select_device_cmd);
}
}
 
 
 
 
int atabug(int argc, char **argv)
int atabug(int argc, char **argv)
{
{
 
 
  /* take care of commandline options                                 */
  /* take care of commandline options                                 */
  if (argc == 0)
        if (argc == 0) {
  {
 
    /* start atabug                                                   */
    /* start atabug                                                   */
    while ( !ata_mon_command() );
    while ( !ata_mon_command() );
  }
        } else
  else
 
    return execute_ata_command(argv[0], argc -1, &argv[1]);
    return execute_ata_command(argv[0], argc -1, &argv[1]);
 
 
  return 0;
        return 0;
}
}
 
 
int atabug_exit(int argc, char **argv)
int atabug_exit(int argc, char **argv)
{
{
  ata_close_cmd(argc, argv);
        ata_close_cmd(argc, argv);
  return -2;
        return -2;
}
}
 
 
/*
/*
 The next code is graceously taken from the "common.c" file
 The next code is graceously taken from the "common.c" file
 and slightly modified to suit the big list of ATA commands
 and slightly modified to suit the big list of ATA commands
 
 
 Better would be if we could access the routines in 'common.c'
 Better would be if we could access the routines in 'common.c'
 directly, using our own set of commands.
 directly, using our own set of commands.
*/
*/
 
 
/* Process command-line, generate arguments */
/* Process command-line, generate arguments */
int ata_mon_command(void)
int ata_mon_command(void)
{
{
  char c = '\0';
        char c = '\0';
  char str[1000];
        char str[1000];
  char *pstr = str;
        char *pstr = str;
  char *command_str;
        char *command_str;
  char *argv[20];
        char *argv[20];
  int argc = 0;
        int argc = 0;
 
 
 
 
  /* Show prompt */
  /* Show prompt */
  printf ("\natabug> ");
        printf("\natabug> ");
 
 
 
 
  /* Get characters from UART */
  /* Get characters from UART */
  c = getc();
  c = getc();
  while (c != '\r' && c != '\f' && c != '\n')
        while (c != '\r' && c != '\f' && c != '\n') {
  {
 
    if (c == '\b')
    if (c == '\b')
      pstr--;
                        pstr--;
    else
                else
      *pstr++ = c;
                        *pstr++ = c;
    putc(c);
                putc(c);
    c = getc();
                c = getc();
  }
        }
  *pstr = '\0';
        *pstr = '\0';
  printf ("\n");
        printf("\n");
 
 
  /* Skip leading blanks */
        /* Skip leading blanks */
  pstr = str;
  pstr = str;
  while ( isspace(*pstr) ) pstr++;
        while (isspace(*pstr))
 
                pstr++;
 
 
  /* Get command from the string */
        /* Get command from the string */
  command_str = pstr;
        command_str = pstr;
 
 
  while (1) {
        while (1) {
    /* Go to next argument */
    /* Go to next argument */
    while ( isgraph(*pstr) ) pstr++;
                while (isgraph(*pstr))
 
                        pstr++;
    if (*pstr) {
    if (*pstr) {
      *pstr++ = '\0';
      *pstr++ = '\0';
      while ( isspace(*pstr) ) pstr++;
                        while (isspace(*pstr))
 
                                pstr++;
      argv[argc++] = pstr;
      argv[argc++] = pstr;
    }
                } else
    else
 
      break;
      break;
  }
        }
 
 
  return execute_ata_command(command_str, argc, argv);
        return execute_ata_command(command_str, argc, argv);
}
}
 
 
 
 
int execute_ata_command(char *command_str, int argc, char **argv)
int execute_ata_command(char *command_str, int argc, char **argv)
{
{
  int i, found = 0;
        int i, found = 0;
 
 
  for (i = 0; i < ata_num_commands; i++)
  for (i = 0; i < ata_num_commands; i++)
    if ( !strcmp(command_str, ata_command[i].name) )
                if (!strcmp(command_str, ata_command[i].name)) {
    {
                        switch (ata_command[i].func(argc, argv)) {
      switch ( ata_command[i].func(argc, argv) )
 
      {
 
        case -1:
        case -1:
          printf ("Missing/wrong parameters, usage: %s %s\n", ata_command[i].name, ata_command[i].params);
                                printf
 
                                    ("Missing/wrong parameters, usage: %s %s\n",
 
                                     ata_command[i].name,
 
                                     ata_command[i].params);
          break;
          break;
 
 
        case -2:
                        case -2:
          return -1;
                                return -1;
      }
                        }
 
 
      found++;
                        found++;
      break;
                        break;
    }
                }
 
 
    if (!found)
        if (!found)
      printf ("Unknown command. Type 'ata help' for help.\n");
                printf("Unknown command. Type 'ata help' for help.\n");
 
 
  return 0;
        return 0;
}
}
 
 
 
void register_ata_command(const char *name, const char *params,
void register_ata_command (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]) )
                          const char *help, int (*func) (int argc,
{
                                                         char *argv[]))
  if (ata_num_commands < MAX_ATA_COMMANDS)
 
  {
  {
 
        if (ata_num_commands < MAX_ATA_COMMANDS) {
    ata_command[ata_num_commands].name = name;
    ata_command[ata_num_commands].name = name;
    ata_command[ata_num_commands].params = params;
                ata_command[ata_num_commands].params = params;
    ata_command[ata_num_commands].help = help;
                ata_command[ata_num_commands].help = help;
    ata_command[ata_num_commands].func = func;
                ata_command[ata_num_commands].func = func;
    ata_num_commands++;
    ata_num_commands++;
  }
        } else
  else
                printf("ata-command '%s' ignored; MAX_COMMANDS limit reached\n",
    printf ("ata-command '%s' ignored; MAX_COMMANDS limit reached\n", name);
                       name);
}
}
 
 
int atabug_help(int argc, char **argv)
int atabug_help(int argc, char **argv)
{
{
  int i;
        int i;
 
 
  for (i = 0; i < ata_num_commands; i++)
  for (i = 0; i < ata_num_commands; i++)
    printf ("%-15s %-17s -%s\n", ata_command[i].name, ata_command[i].params, ata_command[i].help);
                printf("%-15s %-17s -%s\n", ata_command[i].name,
 
                       ata_command[i].params, ata_command[i].help);
 
 
  return 0;
        return 0;
}
}
 
 
 
 
 
 
 
 
/**********************************************************************/
/**********************************************************************/
/*                                                                    */
/*                                                                    */
/*      A T A B U G   C O M M A N D S E T                             */
/*      A T A B U G   C O M M A N D S E T                             */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
/**********************************************************************/
 
 
/*
/*
        A T A _ C L O S E
        A T A _ C L O S E
 
 
        closes the ata_device
        closes the ata_device
*/
*/
int ata_close_cmd(int argc, char **argv)
int ata_close_cmd(int argc, char **argv)
{
{
    inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
        inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
 
 
    return ata_release(inode, filp);
        return ata_release(inode, filp);
}
}
 
 
 
 
/*
/*
        A T A _ D U M P _ D E V I C E _ R E G S
        A T A _ D U M P _ D E V I C E _ R E G S
 
 
        Dumps the (readable) ata-registers.
        Dumps the (readable) ata-registers.
        Exception: status register is not read, this could mask an interrupt
        Exception: status register is not read, this could mask an interrupt
*/
*/
int ata_dump_device_regs_cmd(int argc, char **argv)
int ata_dump_device_regs_cmd(int argc, char **argv)
{
{
    if (argc)
        if (argc)
      printf("\nWARNING: Ignoring invalid argument(s)\n\n");
                printf("\nWARNING: Ignoring invalid argument(s)\n\n");
 
 
 
        printf("Alternate status register : 0x%02lX\n",
    printf("Alternate status register : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_ASR) );
               REG32(ATA_BASE_ADDR + ATA_ASR));
    printf("Cylinder high register    : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_CHR) );
        printf("Cylinder high register    : 0x%02lX\n",
    printf("Cylinder low register     : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_CLR) );
               REG32(ATA_BASE_ADDR + ATA_CHR));
    printf("Device head register      : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_DHR) );
        printf("Cylinder low register     : 0x%02lX\n",
    printf("Error register            : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_ERR) );
               REG32(ATA_BASE_ADDR + ATA_CLR));
    printf("Sector count register     : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_SCR) );
        printf("Device head register      : 0x%02lX\n",
    printf("Sector number register    : 0x%02lX\n", REG32(ATA_BASE_ADDR + ATA_SNR) );
               REG32(ATA_BASE_ADDR + ATA_DHR));
 
        printf("Error register            : 0x%02lX\n",
 
               REG32(ATA_BASE_ADDR + ATA_ERR));
 
        printf("Sector count register     : 0x%02lX\n",
 
               REG32(ATA_BASE_ADDR + ATA_SCR));
 
        printf("Sector number register    : 0x%02lX\n",
 
               REG32(ATA_BASE_ADDR + ATA_SNR));
    printf("Status register (see alternate status register)\n" );
    printf("Status register (see alternate status register)\n" );
 
 
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ D U M P _ H O S T _ R E G S
        A T A _ D U M P _ H O S T _ R E G S
 
 
        Dumps the ata-host registers
        Dumps the ata-host registers
*/
*/
int ata_dump_host_regs_cmd(int argc, char **argv)
int ata_dump_host_regs_cmd(int argc, char **argv)
{
{
    if (argc)
        if (argc)
      printf("\nWARNING: Ignoring invalid argument(s)\n\n");
                printf("\nWARNING: Ignoring invalid argument(s)\n\n");
 
 
 
        printf("Control register                   CTRL : 0x%08lX\n",
    printf("Control register                   CTRL : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_CTRL) );
               REG32(ATA_BASE_ADDR + ATA_CTRL));
    printf("Status register                    STAT : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_STAT) );
        printf("Status register                    STAT : 0x%08lX\n",
    printf("Pio command timing register        PCTR : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PCTR) );
               REG32(ATA_BASE_ADDR + ATA_STAT));
    printf("Pio fast timing register (device0) PFTR0: 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PFTR0) );
        printf("Pio command timing register        PCTR : 0x%08lX\n",
    printf("Pio fast timing register (device1) PFTR1: 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_PFTR1) );
               REG32(ATA_BASE_ADDR + ATA_PCTR));
    printf("Dma timing register (device0)      DTR0 : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_DTR0) );
        printf("Pio fast timing register (device0) PFTR0: 0x%08lX\n",
    printf("Dma timing register (device1)      DTR1 : 0x%08lX\n", REG32(ATA_BASE_ADDR + ATA_DTR1) );
               REG32(ATA_BASE_ADDR + ATA_PFTR0));
 
        printf("Pio fast timing register (device1) PFTR1: 0x%08lX\n",
 
               REG32(ATA_BASE_ADDR + ATA_PFTR1));
 
        printf("Dma timing register (device0)      DTR0 : 0x%08lX\n",
 
               REG32(ATA_BASE_ADDR + ATA_DTR0));
 
        printf("Dma timing register (device1)      DTR1 : 0x%08lX\n",
 
               REG32(ATA_BASE_ADDR + ATA_DTR1));
 
 
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ E N A B L E
        A T A _ E N A B L E
 
 
        clears reset bits
        clears reset bits
*/
*/
int ata_enable_cmd(int argc, char **argv)
int ata_enable_cmd(int argc, char **argv)
{
{
    if (argc != 0)
        if (argc != 0)
        printf("Ignoring invalid parameters\n");
                printf("Ignoring invalid parameters\n");
 
 
    inode->i_rdev = (ATA_BASE_ADDR >> 16);
        inode->i_rdev = (ATA_BASE_ADDR >> 16);
 
 
    // clear hardware reset bit
        // clear hardware reset bit
    if ( ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_HW_RST) )
        if (ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_HW_RST))
      return -1;
                return -1;
 
 
    // clear software reset bit
        // clear software reset bit
    if ( ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_SW_RST) )
        if (ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_SW_RST))
      return -1;
                return -1;
 
 
    // enable ATA Hostcontroller core
        // enable ATA Hostcontroller core
    if ( ata_ioctl(inode, filp, ATA_IOCTL_ENABLE_HOST, 0) )
        if (ata_ioctl(inode, filp, ATA_IOCTL_ENABLE_HOST, 0))
      return -1;
                return -1;
 
 
    printf("ATA host controller enabled\n");
        printf("ATA host controller enabled\n");
 
 
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ E X E C _ C M D
        A T A _ E X E C _ C M D
 
 
        Executes the command; writes the command number in the command register
        Executes the command; writes the command number in the command register
*/
*/
int ata_exec_cmd_cmd(int argc, char **argv)
int ata_exec_cmd_cmd(int argc, char **argv)
{
{
    if (argc != 1)
        if (argc != 1)
        return -1;
                return -1;
 
 
    inode->i_rdev = (ATA_BASE_ADDR >> 16);
        inode->i_rdev = (ATA_BASE_ADDR >> 16);
 
 
    ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, strtoul(*argv, argv, 16) );
        ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, strtoul(*argv, argv, 16));
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ I D E N T I F Y _ D E V I C E
        A T A _ I D E N T I F Y _ D E V I C E
 
 
        Reads the identify_device block and dumps it to the screen
        Reads the identify_device block and dumps it to the screen
*/
*/
int ata_identify_device_cmd(int argc, char **argv)
int ata_identify_device_cmd(int argc, char **argv)
{
{
    unsigned char checksum;
        unsigned char checksum;
 
 
    if (argc != 0)
        if (argc != 0)
        printf("Ignoring invalid parameters\n");
                printf("Ignoring invalid parameters\n");
 
 
 
 
    /* check for busy flag                                            */
    /* check for busy flag                                            */
    if ( ata_dev_busy(ATA_BASE_ADDR) )
        if (ata_dev_busy(ATA_BASE_ADDR))
        printf("Selected ata device busy, ignoring command\n");
        printf("Selected ata device busy, ignoring command\n");
    else
        else {
    {
 
        /* execute identify device                                    */
        /* execute identify device                                    */
        ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
                ata_ioctl(inode, filp, ATA_IOCTL_EXEC_CMD, IDENTIFY_DEVICE);
 
 
        /* read block from ata-device                                 */
                /* read block from ata-device                                 */
        buf[0] = 0;
                buf[0] = 0;
        buf[1] = 1;
                buf[1] = 1;
        ata_ioctl(inode, filp, ATA_IOCTL_READ, (unsigned long) buf);
                ata_ioctl(inode, filp, ATA_IOCTL_READ, (unsigned long)buf);
 
 
        /* dump data to the screen                                    */
                /* dump data to the screen                                    */
        checksum = atabug_dump_data(buf, 512);
                checksum = atabug_dump_data(buf, 512);
 
 
        if (buf[512] == 0xa5)
        if (buf[512] == 0xa5)
            printf("Checksum = 0x%02X (%s)\n", checksum, checksum ? "error" : "OK");
                        printf("Checksum = 0x%02X (%s)\n", checksum,
 
                               checksum ? "error" : "OK");
        else
        else
            printf("No checksum supported\n");
                        printf("No checksum supported\n");
    }
        }
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ O P E N
        A T A _ O P E N
 
 
        opens the ata_device
        opens the ata_device
*/
*/
int ata_open_cmd(int argc, char **argv)
int ata_open_cmd(int argc, char **argv)
{
{
    inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
        inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
 
 
    filp->f_mode = FMODE_READ;
        filp->f_mode = FMODE_READ;
 
 
    if (*argv[1] == 'w')
        if (*argv[1] == 'w')
      filp->f_mode |= FMODE_WRITE;
                filp->f_mode |= FMODE_WRITE;
 
 
    switch( ata_open(inode, filp) ) {
        switch (ata_open(inode, filp)) {
      case EOPENIDEV:
      case EOPENIDEV:
        printf( "Error: Invalid device (invalid MINOR %02X)\n", MINOR(inode->i_rdev) );
                printf("Error: Invalid device (invalid MINOR %02X)\n",
 
                       MINOR(inode->i_rdev));
        break;
        break;
 
 
      case EOPENNODEV:
        case EOPENNODEV:
        printf( "Error: Requested device not found\n" );
                printf("Error: Requested device not found\n");
        break;
                break;
 
 
      case EOPENIHOST:
      case EOPENIHOST:
        printf( "Error: Invalid host (invalid MAJOR %02X)\n", MAJOR(inode->i_rdev) );
                printf("Error: Invalid host (invalid MAJOR %02X)\n",
 
                       MAJOR(inode->i_rdev));
      default:
      default:
        break;
                break;
    }
        }
 
 
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ S E T _ P I O M O D E
        A T A _ S E T _ P I O M O D E
 
 
        Sets the device to the requested PIO mode
        Sets the device to the requested PIO mode
*/
*/
int ata_set_piomode_cmd(int argc, char **argv)
int ata_set_piomode_cmd(int argc, char **argv)
{
{
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ R E A D _ S E C T O R S
        A T A _ R E A D _ S E C T O R S
 
 
        Reads 1 sector from the device and dumps it to the screen
        Reads 1 sector from the device and dumps it to the screen
*/
*/
int ata_read_sectors_cmd(int argc, char **argv)
int ata_read_sectors_cmd(int argc, char **argv)
{
{
    struct request request;
        struct request request;
    unsigned long sector_cnt, sector;
        unsigned long sector_cnt, sector;
 
 
    sector = strtoul(argv[0], argv, 10);
        sector = strtoul(argv[0], argv, 10);
 
 
    switch (argc) {
        switch (argc) {
      case 2:
        case 2:
        sector_cnt = strtoul(argv[1], argv, 10);
                sector_cnt = strtoul(argv[1], argv, 10);
        break;
                break;
 
 
      case 1:
        case 1:
        sector_cnt = 1;
                sector_cnt = 1;
        break;
                break;
 
 
      default:
        default:
        return -1;
                return -1;
    }
        }
 
 
    if ( !sector_cnt )
        if (!sector_cnt) {
    {
 
      printf( "Invalid number of sectors.\n" );
      printf( "Invalid number of sectors.\n" );
      return 0;
                return 0;
    }
        }
 
 
    /* check for busy flag                                            */
        /* check for busy flag                                            */
    if ( ata_dev_busy(ATA_BASE_ADDR) )
        if (ata_dev_busy(ATA_BASE_ADDR))
        printf("Selected ata device busy, ignoring command\n");
        printf("Selected ata device busy, ignoring command\n");
    else
        else {
    {
 
        /* fill the request structure                                 */
        /* fill the request structure                                 */
        request.cmd = READ;
                request.cmd = READ;
        request.sector = sector;
                request.sector = sector;
        request.nr_sectors = sector_cnt;
                request.nr_sectors = sector_cnt;
        request.buffer = buf;
                request.buffer = buf;
 
 
        if ( ata_request(inode, filp, &request) )
                if (ata_request(inode, filp, &request)) {
        {
                        printf
            printf("Error while executing READ_SECTOR(S) command\n");
                            ("Error while executing READ_SECTOR(S) command\n");
            printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
                        printf
        }
                            ("Status register = 0x%02lX, error register = 0x%02lX\n",
        else
                             ata_astatus(ATA_BASE_ADDR),
        {
                             ata_error(ATA_BASE_ADDR));
 
                } else {
            /* dump data to the screen                                    */
            /* dump data to the screen                                    */
            atabug_dump_data(buf, 512 * sector_cnt);
                        atabug_dump_data(buf, 512 * sector_cnt);
        }
                }
    }
        }
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ R E A D _ M B R
        A T A _ R E A D _ M B R
 
 
        Reads master boot record from the device and dumps it's contents to the screen
        Reads master boot record from the device and dumps it's contents to the screen
*/
*/
int ata_read_mbr_cmd(int argc, char **argv)
int ata_read_mbr_cmd(int argc, char **argv)
{
{
    struct request request;
        struct request request;
    unsigned int partition;
        unsigned int partition;
 
 
    // get requested partition number
        // get requested partition number
    partition = 0;
        partition = 0;
    if (argc)
        if (argc)
        partition = strtoul(*argv, argv, 10);
                partition = strtoul(*argv, argv, 10);
 
 
    /* check for busy flag                                            */
        /* check for busy flag                                            */
    if ( ata_dev_busy(ATA_BASE_ADDR) )
        if (ata_dev_busy(ATA_BASE_ADDR))
        printf("Selected ata device busy, ignoring command\n");
        printf("Selected ata device busy, ignoring command\n");
    else
        else {
    {
 
        /* fill the request structure                                 */
        /* fill the request structure                                 */
        request.cmd = READ;
                request.cmd = READ;
        request.sector = 0;
                request.sector = 0;
        request.nr_sectors = 1;
                request.nr_sectors = 1;
        request.buffer = buf;
                request.buffer = buf;
 
 
        if ( ata_request(inode, filp, &request) )
                if (ata_request(inode, filp, &request)) {
        {
 
            printf("Error while reading master boot sector.\n");
            printf("Error while reading master boot sector.\n");
            printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
                        printf
        }
                            ("Status register = 0x%02lX, error register = 0x%02lX\n",
        else
                             ata_astatus(ATA_BASE_ADDR),
        {
                             ata_error(ATA_BASE_ADDR));
 
                } else {
          printf( "Skipping bootloader (446bytes)\n" );
          printf( "Skipping bootloader (446bytes)\n" );
          printf( "Partition %1d:\n", partition);
                        printf("Partition %1d:\n", partition);
 
 
          // abuse partitionnumber to get offset in MBR record
                        // abuse partitionnumber to get offset in MBR record
          partition *= 16;
                        partition *= 16;
          partition += 446;
                        partition += 446;
 
 
          printf( "Bootindicator: 0x%2X (%s)\n", buf[partition], buf[partition] ? "bootable" : "non-bootable");
                        printf("Bootindicator: 0x%2X (%s)\n", buf[partition],
          printf( "Partition start (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
                               buf[partition] ? "bootable" : "non-bootable");
              buf[partition +1], (buf[partition +2] & 0xc0) << 2 | buf[partition +3] ,buf[partition +2] & 0x3f );
                        printf
 
                            ("Partition start (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
 
                             buf[partition + 1],
 
                             (buf[partition + 2] & 0xc0) << 2 | buf[partition +
 
                                                                    3],
 
                             buf[partition + 2] & 0x3f);
          printf( "Systemindicator: 0x%02X (", buf[partition +4]);
          printf( "Systemindicator: 0x%02X (", buf[partition +4]);
 
 
          switch (buf[partition +4])
                        switch (buf[partition + 4]) {
          {
                        case 0:
              case 0: printf ("Non DOS"); break;
                                printf("Non DOS");
              case 1: printf ("DOS FAT12"); break;
                                break;
              case 4: printf ("DOS FAT16"); break;
                        case 1:
              case 5: printf ("DOS extended"); break;
                                printf("DOS FAT12");
              case 6: printf ("DOS >32MByte"); break;
                                break;
 
                        case 4:
 
                                printf("DOS FAT16");
 
                                break;
 
                        case 5:
 
                                printf("DOS extended");
 
                                break;
 
                        case 6:
 
                                printf("DOS >32MByte");
 
                                break;
 
 
              default : printf ("unkown");
                        default:
 
                                printf("unkown");
          };
          };
          printf (")\n");
          printf (")\n");
          printf( "Partition end (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
                        printf
              buf[partition +5], (buf[partition +6] & 0xc0) << 2 | buf[partition +7] ,buf[partition +6] & 0x3f );
                            ("Partition end (head: 0x%02X cyl: 0x%03X sect: 0x%02X)\n",
          printf( "Physical Startsector: 0x%08X\n", buf[partition +11] << 24 |
                             buf[partition + 5],
                                                    buf[partition +10] << 16 |
                             (buf[partition + 6] & 0xc0) << 2 | buf[partition +
                                                    buf[partition +9] << 8   |
                                                                    7],
                                                    buf[partition +8]);
                             buf[partition + 6] & 0x3f);
          printf( "Sector count: 0x%08X\n", buf[partition +15] << 24 |
                        printf("Physical Startsector: 0x%08X\n",
                                            buf[partition +14] << 16 |
                               buf[partition + 11] << 24 | buf[partition +
                                            buf[partition +13] << 8  |
                                                               10] << 16 |
                                            buf[partition +12]);
                               buf[partition + 9] << 8 | buf[partition + 8]);
 
                        printf("Sector count: 0x%08X\n",
 
                               buf[partition + 15] << 24 | buf[partition +
 
                                                               14] << 16 |
 
                               buf[partition + 13] << 8 | buf[partition + 12]);
        }
        }
    }
        }
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ R E A D _ D O S B O O T
        A T A _ R E A D _ D O S B O O T
 
 
        Reads boot sector from the device and dumps it's contents to the screen
        Reads boot sector from the device and dumps it's contents to the screen
*/
*/
int ata_read_dosboot_cmd(int argc, char **argv)
int ata_read_dosboot_cmd(int argc, char **argv)
{
{
    struct request request;
        struct request request;
    unsigned int sector;
        unsigned int sector;
    char txt[8];
        char txt[8];
 
 
    sector = 0;
        sector = 0;
    if (argc)
        if (argc)
      sector = strtoul(*argv, argv, 0);
                sector = strtoul(*argv, argv, 0);
 
 
    /* check for busy flag                                            */
        /* check for busy flag                                            */
    if ( ata_dev_busy(ATA_BASE_ADDR) )
        if (ata_dev_busy(ATA_BASE_ADDR))
        printf("Selected ata device busy, ignoring command\n");
        printf("Selected ata device busy, ignoring command\n");
    else
        else {
    {
 
        /* fill the request structure                                 */
        /* fill the request structure                                 */
        request.cmd = READ;
                request.cmd = READ;
        request.sector = sector;
                request.sector = sector;
        request.nr_sectors = 1;
                request.nr_sectors = 1;
        request.buffer = buf;
                request.buffer = buf;
 
 
        if ( ata_request(inode, filp, &request) )
                if (ata_request(inode, filp, &request)) {
        {
                        printf("Error whilereading boot sector 0x%02X.\n",
            printf("Error whilereading boot sector 0x%02X.\n", sector);
                               sector);
            printf("Status register = 0x%02lX, error register = 0x%02lX\n", ata_astatus(ATA_BASE_ADDR), ata_error(ATA_BASE_ADDR) );
                        printf
        }
                            ("Status register = 0x%02lX, error register = 0x%02lX\n",
        else
                             ata_astatus(ATA_BASE_ADDR),
        {
                             ata_error(ATA_BASE_ADDR));
 
                } else {
          printf( "Reading boot sector 0x%02X\n", sector );
          printf( "Reading boot sector 0x%02X\n", sector );
          printf( "ID number: 0x%2X%2X%2X\n", buf[0], buf[1], buf[2] );
                        printf("ID number: 0x%2X%2X%2X\n", buf[0], buf[1],
 
                               buf[2]);
 
 
          printf( "OEM-name and number: " );
                        printf("OEM-name and number: ");
          memcpy(txt, &buf[3], 8);
                        memcpy(txt, &buf[3], 8);
          txt[8] = '\0';
                        txt[8] = '\0';
          printf( "%s\n", txt );
                        printf("%s\n", txt);
 
 
          printf( "Bytes per sector: %5d\n", (buf[12]<<8) | buf[11] );
                        printf("Bytes per sector: %5d\n",
 
                               (buf[12] << 8) | buf[11]);
          printf( "Sectors per cluster: %3d\n", buf[13] );
          printf( "Sectors per cluster: %3d\n", buf[13] );
          printf( "Reserved IM-sectors: %5d\n", (buf[15]<<8) | buf[14] );
                        printf("Reserved IM-sectors: %5d\n",
 
                               (buf[15] << 8) | buf[14]);
          printf( "Number of FATs: %3d\n", buf[16] );
          printf( "Number of FATs: %3d\n", buf[16] );
          printf( "Number of entries in the root-directory: %5d\n", (buf[18]<<8) | buf[17] );
                        printf("Number of entries in the root-directory: %5d\n",
          printf( "Number of logical sectors: %5d\n", (buf[20]<<8) | buf[19] );
                               (buf[18] << 8) | buf[17]);
 
                        printf("Number of logical sectors: %5d\n",
 
                               (buf[20] << 8) | buf[19]);
          printf( "Medium descriptor byte: %02X\n", buf[21] );
          printf( "Medium descriptor byte: %02X\n", buf[21] );
          printf( "Sectors per FAT: %5d\n", (buf[23]<<8) | buf[22] );
                        printf("Sectors per FAT: %5d\n",
          printf( "Sectors per track: %5d\n", (buf[25]<<8) | buf[24] );
                               (buf[23] << 8) | buf[22]);
          printf( "Number of heads: %5d\n", (buf[27]<<8) | buf[26] );
                        printf("Sectors per track: %5d\n",
          printf( "Number of hidden sectors: %5d\n", (buf[29]<<8) | buf[28] );
                               (buf[25] << 8) | buf[24]);
 
                        printf("Number of heads: %5d\n",
 
                               (buf[27] << 8) | buf[26]);
 
                        printf("Number of hidden sectors: %5d\n",
 
                               (buf[29] << 8) | buf[28]);
        }
        }
    }
        }
    return 0;
        return 0;
}
}
 
 
 
 
/*
/*
        A T A _ R E S E T
        A T A _ R E S E T
 
 
        resets the ATA device, using the select method
        resets the ATA device, using the select method
*/
*/
int ata_reset_cmd(int argc, char **argv)
int ata_reset_cmd(int argc, char **argv)
{
{
    if (argc != 1)
        if (argc != 1)
        return -1;
                return -1;
 
 
    return ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, SET | (**argv - '0') );
        return ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, SET | (**argv - '0'));
}
}
 
 
 
 
/*
/*
        A T A _ S E L E C T _ D E V I C E
        A T A _ S E L E C T _ D E V I C E
 
 
        selects the ATA device; sets the DEV bit in the device/head register
        selects the ATA device; sets the DEV bit in the device/head register
*/
*/
int ata_select_device_cmd(int argc, char **argv)
int ata_select_device_cmd(int argc, char **argv)
{
{
    if (argc != 1)
        if (argc != 1)
      return -1;
                return -1;
 
 
    inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
        inode->i_rdev = (ATA_BASE_ADDR >> 16) | (*argv[0] - '0');
 
 
    ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, **argv - '0');
        ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, **argv - '0');
 
 
    printf("Ata device %1d selected.\n", REG32(ATA_BASE_ADDR + ATA_DHR) & ATA_DHR_DEV ? 1 : 0);
        printf("Ata device %1d selected.\n",
 
               REG32(ATA_BASE_ADDR + ATA_DHR) & ATA_DHR_DEV ? 1 : 0);
    return 0;
    return 0;
}
}
 
 
 
 
 
 
 
 
/**********************************************************************/
/**********************************************************************/
/*                                                                    */
/*                                                                    */
/*      A T A B U G   T O O L S                                       */
/*      A T A B U G   T O O L S                                       */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
/**********************************************************************/
 
 
/*
/*
 D U M P _ D A T A
 D U M P _ D A T A
 
 
 dumps byte-data in a buffer of type short to the screen
 dumps byte-data in a buffer of type short to the screen
 and returns the byte-checksum
 and returns the byte-checksum
 
 
 *buffer = pointer to (short)buffer
 *buffer = pointer to (short)buffer
 cnt     = number of bytes to display
 cnt     = number of bytes to display
*/
*/
unsigned char atabug_dump_data(unsigned char *buffer, int cnt)
unsigned char atabug_dump_data(unsigned char *buffer, int cnt)
{
{
    int i, n, bytes_per_line = 16;
        int i, n, bytes_per_line = 16;
    unsigned char  c, checksum;
        unsigned char c, checksum;
    unsigned char *buf_ptr;
        unsigned char *buf_ptr;
 
 
    /* prepare stored data for display & calculate checksum           */
        /* prepare stored data for display & calculate checksum           */
    checksum = 0;
        checksum = 0;
    buf_ptr = buffer;
        buf_ptr = buffer;
 
 
    /* display data                                                   */
    /* display data                                                   */
    for (i=0; i < cnt; i += bytes_per_line)
        for (i = 0; i < cnt; i += bytes_per_line) {
    {
 
      printf("%3X ", i);
      printf("%3X ", i);
 
 
      /* print hexadecimal notation                                   */
                /* print hexadecimal notation                                   */
      for (n=0; n < bytes_per_line; n++)
                for (n = 0; n < bytes_per_line; n++)
          printf("%02X ", *buf_ptr++);
                        printf("%02X ", *buf_ptr++);
 
 
      buf_ptr -= bytes_per_line; /* back to the start (of this block) */
                buf_ptr -= bytes_per_line;      /* back to the start (of this block) */
 
 
      /* print ASCII notation & calculate checksum                    */
      /* print ASCII notation & calculate checksum                    */
      for (n=0; n < bytes_per_line; n++)
                for (n = 0; n < bytes_per_line; n++) {
      {
 
        c = *buf_ptr++;
        c = *buf_ptr++;
        printf("%c", isprint(c) ? c : '.');
                        printf("%c", isprint(c) ? c : '.');
        checksum += c;
                        checksum += c;
      }
                }
      printf("\n");
                printf("\n");
    }
        }
 
 
    return checksum;
        return checksum;
}
}
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.