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) |
|