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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 920 to Rev 921
    Reverse comparison

Rev 920 → Rev 921

/trunk/orpmon/include/hdbug.h
0,0 → 1,57
/*
atabug.h -- ATA debugging (C-header file)
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
/*
* Definitions for the Opencores ATA Controller Core
*/
 
#ifndef __OC_HDBUG_H
#define __OC_HDBUG_H
 
 
#define HD_DEBUG
 
 
#define MAX_HDBUG_COMMANDS 25
 
/* ---------------------------- */
/* ----- Prototypes ----- */
/* ---------------------------- */
void module_hdbug_init (void);
int hdbug(int argc, char **argv);
int hdbug_exit(int argc, char **argv);
int hdbug_help(int argc, char **argv);
void register_hdbug_command (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]));
int hdbug_mon_command(void);
int execute_hdbug_command(char *pstr, int argc, char **argv);
 
int hdbug_umount_cmd(int arc, char **argv);
int hdbug_mount_cmd(int argc, char **argv);
 
int hdbug_cd_cmd(int argc, char **argv);
 
int hdbug_dir_cmd(int argc, char **argv);
int hdbug_dir_print(struct dos_dir_entry *entry);
 
 
inline void *swap(void *var, size_t size);
 
#endif
/trunk/orpmon/include/atabug.h
0,0 → 1,62
/*
atabug.h -- ATA debugging (C-header file)
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
/*
* Definitions for the Opencores ATA Controller Core
*/
 
#ifndef __OC_ATABUG_H
#define __OC_ATABUG_H
 
 
#define ATA_DEBUG
 
 
#define MAX_ATA_COMMANDS 25
 
/* ---------------------------- */
/* ----- Prototypes ----- */
/* ---------------------------- */
void module_ata_init (void);
int atabug(int argc, char **argv);
int atabug_exit(int argc, char **argv);
int atabug_help(int argc, char **argv);
void register_ata_command (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]));
int ata_mon_command(void);
int execute_ata_command(char *pstr, int argc, char **argv);
 
int ata_close_cmd(int arc, char **argv);
int ata_dump_device_regs_cmd(int argc, char **argv);
int ata_dump_host_regs_cmd(int argc, char **argv);
int ata_enable_cmd(int argc, char **argv);
int ata_exec_cmd_cmd(int argc, char **argv);
int ata_identify_device_cmd(int argc, char **argv);
int ata_open_cmd(int argc, char **argv);
int ata_read_sectors_cmd(int argc, char **argv);
int ata_read_dosboot_cmd(int argc, char **argv);
int ata_reset_cmd(int argc, char **argv);
int ata_select_device_cmd(int argc, char **argv);
int ata_set_piomode_cmd(int argc, char **argv);
 
unsigned char atabug_dump_data(unsigned char *buffer, int cnt);
 
 
#endif
/trunk/orpmon/include/ata.h
3,7 → 3,7
//// ////
//// Include file for OpenCores ATA Controller (OCIDEC) ////
//// ////
//// File : oc_ata.h ////
//// File : ata.h ////
//// Function: c-include file ////
//// ////
//// Authors: Richard Herveille (rherveille@opencores) ////
44,16 → 44,13
#define __OC_ATA_H
 
 
#define ATA_DEBUG
#ifndef REG32
#define REG32(adr) *((volatile unsigned long *)(adr))
#endif
 
 
#define MAX_ATA_COMMANDS 100
typedef unsigned long basetype;
 
 
#ifndef REG32
#define REG32(adr) *((volatile unsigned int *)(adr))
#endif
 
/* --- Register definitions --- */
 
/* ----- Core Registers */
284,27 → 281,179
#define ata_dev_cmdrdy(base) (ata_astatus(base) & (~ATA_SR_BSY & ATA_SR_DRDY))
#define ata_dev_datrdy(base) (ata_astatus(base) & ATA_SR_DRQ)
 
 
 
/*
INTERNALS
*/
 
/* ------------------- */
/* ----- defines ----- */
/* ------------------- */
#define READ 0
#define WRITE 1
 
#define FMODE_READ 0
#define FMODE_WRITE 1
 
#define SET (1<<31)
#define CLR 0
 
 
#define PIO4 0x02
#define PIO3 0x01
 
/*define MAJOR, MINOR numbers */
#define MAJOR(dev) (dev >> 8)
#define MINOR(dev) (dev & 0xff)
 
#define MINOR_DEV0 0x00
#define MINOR_DEV1 0X80
 
 
#define ATA_IOCTL_IDENTIFY_DEVICE 0
#define ATA_IOCTL_IDENTIFY_HOST 1
#define ATA_IOCTL_SELECT_DEVICE 3
#define ATA_IOCTL_SET_RST 4
#define ATA_IOCTL_SET_PIO 5
#define ATA_IOCTL_SET_FEATURES 6
#define ATA_IOCTL_SET_FTE 7
 
#define ARG_HW_RST 0
#define ARG_SW_RST 1
#define ARG_DEV_RST 2
 
/* PIO numbers and PIO timing (in ns) */
#define ARG_PIO4 4
#define ARG_PIO3 3
#define ARG_PIO2 2
#define ARG_PIO1 1
#define ARG_PIO0 0
 
/* register transfer timings */
#define PIO0_RT0 600
#define PIO0_RT1 70
#define PIO0_RT2 290
#define PIO0_RT2I 0
#define PIO0_RT4 30
#define PIO0_RT9 20
 
#define PIO1_RT0 383
#define PIO1_RT1 50
#define PIO1_RT2 290
#define PIO1_RT2I 0
#define PIO1_RT4 20
#define PIO1_RT9 15
 
#define PIO2_RT0 330
#define PIO2_RT1 30
#define PIO2_RT2 290
#define PIO2_RT2I 0
#define PIO2_RT4 15
#define PIO2_RT9 10
 
#define PIO3_RT0 180
#define PIO3_RT1 30
#define PIO3_RT2 80
#define PIO3_RT2I 70
#define PIO3_RT4 10
#define PIO3_RT9 10
 
#define PIO4_RT0 120
#define PIO4_RT1 25
#define PIO4_RT2 70
#define PIO4_RT2I 25
#define PIO4_RT4 10
#define PIO4_RT9 10
 
/* data transfer timings */
#define PIO0_DT0 600
#define PIO0_DT1 70
#define PIO0_DT2 165
#define PIO0_DT2I 0
#define PIO0_DT4 30
#define PIO0_DT9 20
 
#define PIO1_DT0 383
#define PIO1_DT1 50
#define PIO1_DT2 125
#define PIO1_DT2I 0
#define PIO1_DT4 20
#define PIO1_DT9 15
 
#define PIO2_DT0 240
#define PIO2_DT1 30
#define PIO2_DT2 100
#define PIO2_DT2I 0
#define PIO2_DT4 15
#define PIO2_DT9 10
 
#define PIO3_DT0 180
#define PIO3_DT1 30
#define PIO3_DT2 80
#define PIO3_DT2I 70
#define PIO3_DT4 10
#define PIO3_DT9 10
 
#define PIO4_DT0 120
#define PIO4_DT1 25
#define PIO4_DT2 70
#define PIO4_DT2I 25
#define PIO4_DT4 10
#define PIO4_DT9 10
 
 
 
/* error numbers */
#define EINVAL -1
#define EIOCTLIARG -2
 
#define EOPENIDEV -3
#define EOPENIHOST -4
#define EOPENNODEV -5
 
 
 
 
/* ------------------------------ */
/* ----- structs & typedefs ----- */
/* ------------------------------ */
struct inode {
unsigned short i_rdev;
};
 
struct file {
unsigned long f_mode;
unsigned long f_flags;
};
 
typedef unsigned int dev_t;
 
struct request {
dev_t rq_dev;
int cmd;
unsigned long sector;
unsigned long nr_sectors;
unsigned char *buffer;
};
 
 
/* ---------------------------- */
/* ----- Prototypes ----- */
/* ---------------------------- */
void module_ata_init (void);
int atabug(int argc, char **argv);
int atabug_exit(int argc, char **argv);
int atabug_help(int argc, char **argv);
void register_ata_command (const char *name, const char *params, const char *help, int (*func)(int argc, char *argv[]));
int ata_mon_command(void);
int execute_ata_command(char *pstr, int argc, char **argv);
int ata_open(struct inode *inode, struct file *filp);
int ata_open_device_not_found(struct inode *inode);
 
int ata_dump_device_regs_cmd(int argc, char **argv);
int ata_dump_host_regs_cmd(int argc, char **argv);
int ata_enable_cmd(int argc, char **argv);
int ata_exec_cmd_cmd(int argc, char **argv);
int ata_identify_device_cmd(int argc, char **argv);
int ata_read_sector_cmd(int argc, char **argv);
int ata_reset_cmd(int argc, char **argv);
int ata_select_device_cmd(int argc, char **argv);
int ata_release(struct inode *inode, struct file *filp);
 
unsigned char atabug_dump_data(unsigned short *buffer, int cnt);
int ata_ioctl(struct inode *inode, struct file *filp, unsigned command, unsigned long argument);
unsigned long ata_calc_pio_timing(short t0, short t1, short t2, short t4, short t2i, short t9);
 
int ata_check_media_change(dev_t dev);
 
int ata_revalidate(dev_t dev);
 
int ata_request(struct inode *inode, struct file *filp, struct request *request);
 
 
#endif
/trunk/orpmon/include/string.h
0,0 → 1,45
/*
string.h -- String manipulation
Implements (some) of the standard string routines
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
#ifndef __STRING_H
#define __STRING_H
#include <stddef.h>
 
/* Basic string functions */
extern size_t strlen(const char *s);
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n);
extern char *strcat(char *dest, const char *src);
extern char *strncat(char *dest, const char *src, size_t n);
extern int strcmp(const char *s1, const char *s2);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern char *strchr(const char *s, int c);
extern char *strrchr(const char *s, int c);
 
/* Basic mem functions */
extern void *memcpy(void *dest, const void *src, size_t n);
extern void *memmove(void *dest, void *src, size_t n);
extern int memcmp(const void *s1, const void *s2, size_t n);
extern void *memchr(const void *s, int c, size_t n);
extern void *memset(void *d, int c, size_t n);
 
#endif
/trunk/orpmon/include/support.h
9,6 → 9,8
#include <stddef.h>
#include <limits.h>
 
#include "string.h"
 
/* Register access macros */
#define REG8(add) *((volatile unsigned char *)(add))
#define REG16(add) *((volatile unsigned short *)(add))
33,15 → 35,18
extern void exit (int i) __attribute__ ((__noreturn__));
 
/* some stdlib functions */
 
/* defined in 'string.h'
extern void *memcpy (void *dest, const void *src, unsigned long n);
extern void *memmove (void *dest, const void *src, unsigned long n);
int memcmp (void *dstvoid, const void *srcvoid, unsigned long length);
extern void *memset (void * dstvoid, const char data, unsigned long length);
extern void *memchr(const void *s, int c, unsigned long n);
extern unsigned long strtoul (const char *str, char **endptr, int base);
extern int strlen (const char *src);
extern int strcmp (const char *s1, const char *s2);
extern char *strcpy (char *dst0, char *src0);
*/
extern unsigned long strtoul (const char *str, char **endptr, int base);
 
/* defined in 'ctype.h'
#define isspace(c) ((c) == ' ' || (c) == '\t')
/trunk/orpmon/include/ctype.h
3,7 → 3,7
Implements the usual ctype stuff (only valid for ASCII systems)
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
/trunk/orpmon/include/dos.h
0,0 → 1,94
/*
dos.h -- dos services (C-header file)
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
/*
* Definitions for the Opencores ATA Controller Core
*/
 
#ifndef __OC_DOS_H
#define __OC_DOS_H
 
#include "ata.h"
 
struct dosparam {
unsigned short bytes_per_sector;
unsigned char fats; // number of FATs
unsigned char sectors_per_cluster;
unsigned short sectors_per_fat;
unsigned short root_entries; // number of entries in the root sector
 
unsigned long ssector; // startsector of current directory
unsigned long csector; // startsector of current cluster
unsigned long sentry; // startentry of current cluster
unsigned char cbuf[2048]; // cluster buffer. This should be dynamically alocated
 
/* ata driver structures */
struct inode inode;
struct file filp;
struct request request;
};
 
 
struct dos_dir_entry {
unsigned char name[8];
unsigned char ext[3];
 
unsigned char attribute; // attributes
 
unsigned char reserved[10];
 
unsigned short time; // time of creation/modification
unsigned short date; // date of creation/modification
 
unsigned short sc; // startcluster
unsigned long size; // file size
};
 
 
#define ATT_ARC 0x20
#define ATT_DIR 0x10
#define ATT_LAB 0x08
#define ATT_SYS 0x04
#define ATT_HID 0x02
#define ATT_RW 0x01
 
 
/*
macros
*/
#define bytes_per_cluster(param) (unsigned long)(param->sectors_per_cluster * param->bytes_per_sector)
#define entries_per_cluster(param) (unsigned long)(bytes_per_cluster(param) / sizeof(struct dos_dir_entry) )
 
 
/*
prototypes
*/
int dos_open(struct dosparam *params);
int dos_release(struct dosparam *params);
 
struct dos_dir_entry *dos_dir_get_entry(struct dosparam *params, unsigned long entry);
struct dos_dir_entry *dos_dir_find_entry(struct dosparam *params, const char *name);
 
char *dos_read_cluster(struct dosparam *params, unsigned long ssector);
char *dos_dir_cluster_read_nxt(struct dosparam *params);
char *dos_dir_cluster_reset(struct dosparam *params);
 
#endif
/trunk/orpmon/common/ctype.c
3,7 → 3,7
Implements the usual ctype stuff (only valid for ASCII systems)
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
/trunk/orpmon/common/string.c
0,0 → 1,247
/*
string.h -- String manipulation
Implements (some) of the standard string routines
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
#include <stddef.h>
#include "string.h"
 
/* Basic string functions */
 
/*
s t r l e n
 
returns number of characters in s (not including terminating null character)
*/
size_t strlen(const char *s)
{
size_t cnt = 0;
 
/* count the length of string s, not including the \0 character */
while (*s++)
cnt++;
 
return cnt;
}
 
/*
s t r c p y
 
Copy 'src' to 'dest'. Strings may not overlap.
*/
char *strcpy(char *dest, const char *src)
{
char *d = dest;
 
/* copy src to dest */
while ( (*dest++ = *src++) )
;
 
return d;
}
 
 
char *strncpy(char *dest, const char *src, size_t n)
{
char *d = dest;
 
/* copy src to dest */
while ( *src && n ) {
*dest++ = *src++;
n--;
}
 
/* fill the remainder of d with nulls */
while (n--)
*dest++ = '\0';
 
return d;
}
 
 
char *strcat(char *dest, const char *src)
{
char *d = dest;
 
/* find the end of the destination string */
while (*dest++)
;
 
/* append the source string to the destination string */
while ( (*dest++ = *src++) )
;
 
return d;
}
 
 
char *strncat(char *dest, const char *src, size_t n)
{
char *d = dest;
 
/* find the end of the destination string */
while (*dest++)
;
 
/* copy src to dest */
while ( (*dest = *src) && n-- ) {
dest++;
src++;
}
 
 
/* add terminating '\0' character */
*dest = '\0';
 
return d;
}
 
 
int strcmp(const char *s1, const char *s2)
{
while ( *s1 && (*s1 == *s2) ) {
s1++;
s2++;
}
 
return *s1 - *s2;
}
 
 
int strncmp(const char *s1, const char *s2, size_t n)
{
while ( *s1 && (*s1 == *s2) && n-- ) {
s1++;
s2++;
}
 
return *s1 - *s2;
}
 
 
char *strchr(const char *s, int c)
{
/* search for the character c */
while (*s && (*s != c) )
s++;
 
return (char *)s;
}
 
 
char *strrchr(const char *s, int c)
{
char *fnd = NULL;
 
/* search for the character c */
while (*s) {
if (*s == c)
fnd = (char *)s;
s++;
}
 
return fnd;
}
 
 
/* Basic mem functions */
void *memcpy(void *dest, const void *src, size_t n)
{
/* check if 'src' and 'dest' are on LONG boundaries */
if ( (sizeof(unsigned long) -1) & ((unsigned long)dest | (unsigned long)src) )
{
/* no, do a byte-wide copy */
char *cs = (char *) src;
char *cd = (char *) dest;
 
while (n--)
*cd++ = *cs++;
}
else
{
/* yes, speed up copy process */
/* copy as many LONGs as possible */
long *ls = (long *)src;
long *ld = (long *)dest;
 
size_t cnt = n >> 2;
while (cnt--)
*ld++ = *ls++;
 
/* finally copy the remaining bytes */
char *cs = (char *) (src + (n & ~0x03));
char *cd = (char *) (dest + (n & ~0x03));
 
cnt = n & 0x3;
while (cnt--)
*cd++ = *cs++;
}
 
return dest;
}
 
 
void *memmove(void *dest, void *src, size_t n)
{
char *d = dest;
char *s = src;
 
while (n--)
*d++ = *s++;
 
return dest;
}
 
 
int memcmp(const void *s1, const void *s2, size_t n)
{
char *p1 = (void *)s1;
char *p2 = (void *)s2;
 
while ( (*p1 == *p2) && n-- ) {
p1++;
p2++;
}
 
return *p1 - *p2;
}
 
 
void *memchr(const void *s, int c, size_t n)
{
char *p = (void *)s;
 
/* search for the character c */
while ( (*p != c) && n-- )
p++;
 
return (*p == c) ? p : NULL;
}
 
 
void *memset(void *s, int c, size_t n)
{
char *p = s;
 
while (n--)
*p++ = c;
 
return s;
}
/trunk/orpmon/common/common.c
235,6 → 235,7
void tick_init(void);
void module_touch_init (void);
void module_ata_init (void);
void module_hdbug_init (void);
 
/* List of all initializations */
void mon_init (void)
262,6 → 263,7
module_load_init ();
module_touch_init ();
module_ata_init ();
module_hdbug_init ();
 
tick_init();
}
/trunk/orpmon/common/Makefile
3,7 → 3,7
 
LIB = common_o.o
 
OBJS = common.o support.o cprintf.o screen.o font.o ctype.o
OBJS = common.o support.o cprintf.o screen.o font.o ctype.o string.o
SOBJS = or32.o
 
all: $(LIB)
/trunk/orpmon/common/support.c
22,7 → 22,7
/* activate printf support in simulator */
void __printf(const char *fmt, ...)
{
 
va_list args;
va_start(args, fmt);
__asm__ __volatile__ (" l.addi\tr3,%1,0\n \
44,102 → 44,20
 
/* For writing into SPR. */
void mtspr(unsigned long spr, unsigned long value)
{
{
asm("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
}
 
/* For reading SPR. */
unsigned long mfspr(unsigned long spr)
{
{
unsigned long value;
asm("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
return value;
}
 
void *memcpy (void *dstv, const void *srcv, unsigned long length)
{
char *dst = dstv;
const char *src = (const char *) srcv;
 
while (length--)
*dst++ = *src++;
return dst;
}
 
void *memmove (void *dstv, const void *srcv, unsigned long length)
{
char *dst = dstv;
const char *src = srcv;
 
/* Copy backwards? */
if (src < dst && dst < src + length) {
src += length;
dst += length;
while (length--) *--dst = *--src;
return dstv;
} else return memcpy (dstv, srcv, length);
}
 
int memcmp (void *dstv, const void *srcv, unsigned long length)
{
char *dst = dstv;
const char *src = (const char *) srcv;
 
while (length--)
if(*dst++ != *src++) {
if(*(--dst) > *(--src))
return 1;
else
return -1;
}
return 1;
}
 
void *memset (void *dstvoid, const char data, unsigned long length)
{
char *dst = dstvoid;
while (length--) *dst++ = data;
return dst;
}
 
void *memchr(const void *s, int c, unsigned long n)
{
char *sc = (char *)s;
int i;
for (i = 0; i < n; i++)
if (*sc == c) return sc;
else sc++;
return sc;
}
 
int strlen (const char *src)
{
int len = 0;
while (*src++) len++;
return len;
}
 
int strcmp (const char *s1, const char *s2)
{
while (*s1 != '\0' && *s1 == *s2) {
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
}
 
char *strcpy (char *dst0, char *src0)
{
char *s = dst0;
while ((*dst0++ = *src0++));
return s;
}
 
void reset_timer (void)
{
timestamp = 0;
}
 
/* Parses hex or decimal number */
unsigned long strtoul (const char *str, char **endptr, int base)
{
154,7 → 72,7
fail_char = pos;
if ((*pos == 'x') || (*pos == 'X')) ++pos;
}
 
if (base == 0) { /* dynamic base */
base = 10; /* default is 10 */
if (*pos == '0') {
/trunk/orpmon/drivers/ata.c
0,0 → 1,517
/*
ata.c -- ATA driver
Copyright (C) 2002 Richard Herveille, rherveille@opencores.org
 
This file is part of OpenRISC 1000 Reference Platform Monitor (ORPmon)
 
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
 
#include <string.h>
 
/* get prototype for 'printf'
get IN_CLOCK (from 'board.h')
*/
#include "common.h"
#include "ata.h"
 
 
/*
static constants (yuck, yuck, yuck)
*/
static int usage[2] = {0, 0};
static int hardsect_size[2] = {512, 512};
static int current_pio_mode = 9999;
 
/*
local defines
*/
#define TYPE(devid) (devid >> 4)
#define REV(devid) (devid & 0xf)
 
#define BASE(inode) ( (unsigned long) (MAJOR(inode->i_rdev) << 24) )
#define DEVICE(inode) ( MINOR(inode->i_rdev) )
 
#define IN_CLK_MHZ (IN_CLK / 1000000)
#define TO_TICKS(time) ( ((time + (IN_CLK_MHZ >> 1)) / IN_CLK_MHZ) -1 )
 
 
/*
A T A _ O P E N
 
opens ata device;
- identifies ata-device-id
- programs ata-host
 
MAJOR: atahost identification (base address)
MINOR: atadevice identification (MSB=0: device0, MSB=1: device1)
*/
int ata_open(struct inode *inode, struct file *filp)
{
unsigned int atahost, device;
unsigned short buf[256];
unsigned short dev_pio;
unsigned long sectors;
 
char txt[41];
 
/* check device-id (MINOR number) */
if ( (device = DEVICE(inode)) > 1 )
return EOPENIDEV;
 
/* get atahost id */
atahost = ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_HOST, 0);
if (atahost)
{
printf( "OCIDEC-%1d, revision 0x%02X found at 0x%08lX.\n", TYPE(atahost), REV(atahost), BASE(inode) );
}
else
{
printf( "No OCIDEC device found.\n" );
return EOPENIHOST;
}
 
 
/* check if the host has been opened already */
if (!usage[device]++)
{
/* no, take device out of reset */
ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, CLR | ARG_HW_RST);
 
/* program PIO timing registers (set to PIO mode 0) */
ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO0);
}
 
/* select requested device */
ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, 0);
 
/* identify requested ata-devices */
ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_DEVICE, (unsigned long) buf);
 
/* check if a valid device was found */
/* bit 15 in identify_device word0 must be '0',
or be equal to 0x848a (CFA feature set) */
if ( (buf[0] & 0x8000) && (buf[0] != 0x848a) )
{
ata_release(inode, filp);
return EOPENNODEV;
}
 
/* Then check specific configuration word */
switch(buf[2]) {
case 0x37c8:
/* device does require SET_FEATURES
IDENTIFY_DEVICE response is incomplete */
case 0x738c:
/* device does require SET_FEATURES
IDENTIFY_DEVICE response is complete */
ata_ioctl(inode, filp, ATA_IOCTL_SET_FEATURES, 0); //FIXME
break;
case 0x8c73:
/* device does not require SET_FEATURES
IDENTIFY_DEVICE response is incomplete */
case 0xc837:
/* device does not require SET_FEATURES
IDENTIFY_DEVICE response is complete */
break;
 
default:
ata_release(inode, filp);
return EOPENNODEV;
}
 
/* checks ok */
 
/* extract data from device */
printf( "Device%1d: ", device);
 
/* display device model, serialnumber, and firmware revision */
memcpy(txt, &buf[27], 40);
txt[40] = '\0';
printf( "%s ", txt );
 
memcpy(txt, &buf[10], 20);
txt[20] = '\0';
printf( "%s ", txt );
 
memcpy( txt, &buf[23], 8);
txt[8] = '\0';
printf( "%s\n", txt );
 
/* display size in MBytes */
sectors = (buf[61] << 16) | buf[60];
printf( " %ld MBytes ", sectors >> 11 ); /* assuming 512bytes per sector */
 
/* get supported pio modes */
dev_pio = buf[64];
 
/* program ocidec timing registers to highest possible pio mode */
if (dev_pio & PIO4)
{
printf("PIO-4 supported\n");
ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO4);
}
else if (dev_pio & PIO3)
{
printf("PIO-3 supported\n");
ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO3);
}
else
{
printf("PIO-2 supported\n");
ata_ioctl(inode, filp, ATA_IOCTL_SET_PIO, ARG_PIO2);
}
 
return 0;
}
 
 
/*
A T A _ R E L E A S E
 
closes ata device;
*/
int ata_release(struct inode *inode, struct file *filp)
{
/* decrease usage count */
if (!--usage[DEVICE(inode)])
{
/* reset atahost */
ata_ioctl(inode, filp, ATA_IOCTL_SET_RST, SET | ARG_HW_RST);
}
 
return 0;
}
 
 
 
/*
A T A _ I O C T L
*/
int ata_ioctl(struct inode *inode, struct file *filp, unsigned command, unsigned long argument)
{
unsigned long base = BASE(inode);
 
switch (command)
{
case ATA_IOCTL_IDENTIFY_DEVICE:
/* Reads the identify_device block */
{
int i;
unsigned short *buf_ptr = (short *)argument;
 
/* send 'identify_device' command */
REG32(base + ATA_CR) = IDENTIFY_DEVICE;
 
/* read data from devices and store it in buffer */
for (i=0; i < 256; i++)
*buf_ptr++ = REG32(base + ATA_DR);
 
return 0;
}
 
 
case ATA_IOCTL_IDENTIFY_HOST:
/* reads OCIDEC status register configuration bits */
return (REG32(base + ATA_STAT) >> 24);
 
 
case ATA_IOCTL_SELECT_DEVICE:
/* selects ATA device
sets the DEV bit in the device/head register */
if ( DEVICE(inode) )
REG32(base + ATA_DHR) |= ATA_DHR_DEV; /* select device1 */
else
REG32(base + ATA_DHR) &= ~ATA_DHR_DEV; /* select device0 */
 
return 0;
 
 
case ATA_IOCTL_SET_FTE:
/* set FTE bits */
if ( MINOR(inode->i_rdev) )
if (argument)
REG32(base + ATA_CTRL) |= ATA_IORDY_FTE0;
else
REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE0;
else
if (argument)
REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
else
REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
 
return 0;
 
 
case ATA_IOCTL_SET_PIO:
/* programs the PIO timing registers */
{
unsigned long timing;
unsigned short buf[256];
 
/* do we need to read the identify_device block ?? */
if (argument & (ARG_PIO4 | ARG_PIO3) )
ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_DEVICE, (unsigned long) buf);
 
/* program register transfer timing registers */
/* set the slowest pio mode for register transfers */
if (argument < current_pio_mode)
{
switch (argument)
{
case ARG_PIO4:
if ( (buf[53] & 0x01) && buf[68] )
timing = ata_calc_pio_timing(buf[68], PIO4_RT1, PIO4_RT2, PIO4_RT4, PIO4_RT2I, PIO4_RT9);
else
timing = ata_calc_pio_timing(PIO4_RT0, PIO4_RT1, PIO4_RT2, PIO4_RT4, PIO4_RT2I, PIO4_RT9);
break;
 
case ARG_PIO3:
if ( (buf[53] & 0x01) && buf[68] )
timing = ata_calc_pio_timing(buf[68], PIO3_RT1, PIO3_RT2, PIO3_RT4, PIO3_RT2I, PIO3_RT9);
else
timing = ata_calc_pio_timing(PIO3_RT0, PIO3_RT1, PIO3_RT2, PIO3_RT4, PIO3_RT2I, PIO3_RT9);
break;
 
case ARG_PIO2:
timing = ata_calc_pio_timing(PIO2_RT0, PIO2_RT1, PIO2_RT2, PIO2_RT4, PIO2_RT2I, PIO2_RT9);
break;
 
case ARG_PIO1:
timing = ata_calc_pio_timing(PIO1_RT0, PIO1_RT1, PIO1_RT2, PIO1_RT4, PIO1_RT2I, PIO1_RT9);
break;
 
default: /* PIO mode 0 */
timing = ata_calc_pio_timing(PIO0_RT0, PIO0_RT1, PIO0_RT2, PIO0_RT4, PIO0_RT2I, PIO0_RT9);
break;
}
 
/* program IORDY bit */
if (argument & (ARG_PIO4 | ARG_PIO3) )
REG32(base + ATA_CTRL) |= ATA_IORDY;
else
REG32(base + ATA_CTRL) &= ~ATA_IORDY;
 
/* program register transfer timing registers */
REG32(base + ATA_PCTR) = timing;
 
current_pio_mode = argument;
}
 
/* Program data transfer timing registers */
if ( TYPE(ata_ioctl(inode, filp, ATA_IOCTL_IDENTIFY_HOST, 0)) > 1 )
{
switch (argument)
{
case ARG_PIO4:
if ( (buf[53] & 0x01) && buf[68] )
timing = ata_calc_pio_timing(buf[68], PIO4_DT1, PIO4_DT2, PIO4_DT4, PIO4_DT2I, PIO4_DT9);
else
timing = ata_calc_pio_timing(PIO4_DT0, PIO4_DT1, PIO4_DT2, PIO4_DT4, PIO4_DT2I, PIO4_DT9);
break;
 
case ARG_PIO3:
if ( (buf[53] & 0x01) && buf[68] )
timing = ata_calc_pio_timing(buf[68], PIO3_DT1, PIO3_DT2, PIO3_DT4, PIO3_DT2I, PIO3_DT9);
else
timing = ata_calc_pio_timing(PIO3_DT0, PIO3_DT1, PIO3_DT2, PIO3_DT4, PIO3_DT2I, PIO3_DT9);
break;
 
case ARG_PIO2:
timing = ata_calc_pio_timing(PIO2_DT0, PIO2_DT1, PIO2_DT2, PIO2_DT4, PIO2_DT2I, PIO2_DT9);
break;
 
case ARG_PIO1:
timing = ata_calc_pio_timing(PIO1_DT0, PIO1_DT1, PIO1_DT2, PIO1_DT4, PIO1_DT2I, PIO1_DT9);
break;
 
default: /* PIO mode 0 */
timing = ata_calc_pio_timing(PIO0_DT0, PIO0_DT1, PIO0_DT2, PIO0_DT4, PIO0_DT2I, PIO0_DT9);
break;
}
 
/* program data transfer timing registers, set IORDY bit */
if ( MINOR(inode->i_rdev) )
{
REG32(base + ATA_PFTR1) = timing;
 
/* program IORDY bit */
if ( argument & (ARG_PIO4 | ARG_PIO3) )
REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
else
REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
}
else
{
REG32(base + ATA_PFTR0) = timing;
 
/* program IORDY bit */
if ( argument & (ARG_PIO4 | ARG_PIO3) )
REG32(base + ATA_CTRL) |= ATA_IORDY_FTE1;
else
REG32(base + ATA_CTRL) &= ~ATA_IORDY_FTE1;
}
 
/* enable data transfer timing */
ata_ioctl(inode, filp, ATA_IOCTL_SET_FTE, 1);
}
 
return 0;
}
 
 
case ATA_IOCTL_SET_RST:
/* sets or clears reset bits */
if (argument & SET)
switch (argument & ~SET) {
case ARG_HW_RST: /* ata hardware reset */
REG32(base + ATA_CTRL) |= ATA_RST;
return 0;
 
case ARG_SW_RST: /* ata software reset */
REG32(base + ATA_DCR) |= ATA_DCR_RST;
return 0;
 
case ARG_DEV_RST: /* ata device reset */
REG32(base + ATA_CR) = DEVICE_RESET;
return 0;
 
default:
return EIOCTLIARG;
}
else
{
switch(argument & ~SET) {
case ARG_HW_RST: /* ata hardware reset */
REG32(base + ATA_CTRL) &= ~ATA_RST;
return 0;
 
case ARG_SW_RST: /* ata software reset */
REG32(base + ATA_DCR) &= ~ATA_DCR_RST;
return 0;
 
case ARG_DEV_RST: /* ata device reset */
return 0;
 
default:
return EIOCTLIARG;
}
}
 
 
default:
printf( "FIXME: Unsupported IOCTL call\n" );
return EINVAL;
}
}
 
 
unsigned long ata_calc_pio_timing(short t0, short t1, short t2, short t4, short t2i, short t9)
{
int teoc;
 
teoc = t0 - t1 - t2;
 
if (teoc < 0)
teoc = 0;
 
if (t9 > teoc)
teoc = t9;
 
if (t2i > teoc)
teoc = t2i;
 
t1 = TO_TICKS(t1);
t2 = TO_TICKS(t2);
t4 = TO_TICKS(t4);
teoc = TO_TICKS(teoc);
 
return (teoc << ATA_TEOC) | (t4 << ATA_T4) | (t2 << ATA_T2) | (t1 << ATA_T1);
}
 
 
/*
A T A _ R E Q U E S T
*/
int ata_request(struct inode *inode, struct file *filp, struct request *request)
{
unsigned int device = MINOR(inode->i_rdev);
unsigned long base = BASE(inode);
unsigned int sector_size;
 
/* get the sector size for the current device */
sector_size = hardsect_size[device] >> 1;
 
/* set the device */
ata_ioctl(inode, filp, ATA_IOCTL_SELECT_DEVICE, device);
 
/* get the base address */
base = BASE(inode);
 
switch (request->cmd) {
case READ:
{
register unsigned long i, n;
register unsigned short rd_data;
register char *buf_ptr;
 
/* program ata-device registers */
REG32(base + ATA_DHR) = ((request->sector >> 24) & ATA_DHR_H) | ATA_DHR_LBA;
REG32(base + ATA_CHR) = (request->sector >> 16) & 0xff;
REG32(base + ATA_CLR) = (request->sector >> 8) & 0xff;
REG32(base + ATA_SNR) = request->sector & 0xff;
 
REG32(base + ATA_SCR) = request->nr_sectors;
 
/* send 'read_sector(s)' command */
REG32(base + ATA_CR) = READ_SECTORS;
 
/* check status & error registers */
if ( ata_astatus(base) & ATA_SR_ERR)
return -1;
 
/* read data from devices and store it in the buffer */
buf_ptr = request->buffer;
 
for (n=0; n < request->nr_sectors; n++)
for (i=0; i < sector_size; i++)
{
rd_data = REG32(base + ATA_DR);
 
/* the data is byte reversed, swap high & low bytes */
*buf_ptr++ = rd_data;
*buf_ptr++ = rd_data >> 8;
}
 
return 0;
}
 
 
case WRITE:
/* check if device may be written to */
if (filp->f_mode & FMODE_WRITE)
{
/* do the write stuff */
}
else
return EINVAL;
 
 
default:
return EINVAL;
}
 
return 0;
}
/trunk/orpmon/drivers/Makefile
1,6 → 1,6
 
LIB = drivers.o
OBJS = int.o eth.o uart.o tick.o flash.o keyboard.o spi.o
OBJS = int.o eth.o uart.o tick.o flash.o keyboard.o spi.o ata.o
 
all: $(LIB)
 

powered by: WebSVN 2.1.0

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