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

Subversion Repositories eco32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /eco32/trunk
    from Rev 195 to Rev 196
    Reverse comparison

Rev 195 → Rev 196

/stdalone/dmpmbr/iolib.c
0,0 → 1,329
/*
* iolib.c -- I/O library
*/
 
 
#include "types.h"
#include "stdarg.h"
#include "iolib.h"
#include "biolib.h"
 
 
/**************************************************************/
 
/* string functions */
 
 
int strlen(char *str) {
int i;
 
i = 0;
while (*str++ != '\0') {
i++;
}
return i;
}
 
 
void strcpy(char *dst, char *src) {
while ((*dst++ = *src++) != '\0') ;
}
 
 
void memcpy(unsigned char *dst, unsigned char *src, unsigned int cnt) {
while (cnt--) {
*dst++ = *src++;
}
}
 
 
/**************************************************************/
 
/* terminal I/O */
 
 
char getchar(void) {
return getc();
}
 
 
void putchar(char c) {
if (c == '\n') {
putchar('\r');
}
putc(c);
}
 
 
void putString(char *s) {
while (*s != '\0') {
putchar(*s++);
}
}
 
 
/**************************************************************/
 
/* get a line from the terminal */
 
 
void getLine(char *prompt, char *line, int max) {
int index;
char c;
 
putString(prompt);
putString(line);
index = strlen(line);
while (1) {
c = getchar();
switch (c) {
case '\r':
putchar('\n');
line[index] = '\0';
return;
case '\b':
case 0x7F:
if (index == 0) {
break;
}
putchar('\b');
putchar(' ');
putchar('\b');
index--;
break;
default:
if (c == '\t') {
c = ' ';
}
if (c < 0x20 || c > 0x7E) {
break;
}
putchar(c);
line[index++] = c;
break;
}
}
}
 
 
/**************************************************************/
 
/* scaled-down version of printf */
 
 
/*
* Count the number of characters needed to represent
* a given number in base 10.
*/
int countPrintn(long n) {
long a;
int res;
 
res = 0;
if (n < 0) {
res++;
n = -n;
}
a = n / 10;
if (a != 0) {
res += countPrintn(a);
}
return res + 1;
}
 
 
/*
* Output a number in base 10.
*/
void printn(long n) {
long a;
 
if (n < 0) {
putchar('-');
n = -n;
}
a = n / 10;
if (a != 0) {
printn(a);
}
putchar(n % 10 + '0');
}
 
 
/*
* Count the number of characters needed to represent
* a given number in a given base.
*/
int countPrintu(unsigned long n, unsigned long b) {
unsigned long a;
int res;
 
res = 0;
a = n / b;
if (a != 0) {
res += countPrintu(a, b);
}
return res + 1;
}
 
 
/*
* Output a number in a given base.
*/
void printu(unsigned long n, unsigned long b, Bool upperCase) {
unsigned long a;
 
a = n / b;
if (a != 0) {
printu(a, b, upperCase);
}
if (upperCase) {
putchar("0123456789ABCDEF"[n % b]);
} else {
putchar("0123456789abcdef"[n % b]);
}
}
 
 
/*
* Output a number of filler characters.
*/
void fill(int numFillers, char filler) {
while (numFillers-- > 0) {
putchar(filler);
}
}
 
 
/*
* Formatted output with a variable argument list.
*/
void vprintf(char *fmt, va_list ap) {
char c;
int n;
long ln;
unsigned int u;
unsigned long lu;
char *s;
Bool negFlag;
char filler;
int width, count;
 
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
return;
}
putchar(c);
}
c = *fmt++;
if (c == '-') {
negFlag = TRUE;
c = *fmt++;
} else {
negFlag = FALSE;
}
if (c == '0') {
filler = '0';
c = *fmt++;
} else {
filler = ' ';
}
width = 0;
while (c >= '0' && c <= '9') {
width *= 10;
width += c - '0';
c = *fmt++;
}
if (c == 'd') {
n = va_arg(ap, int);
count = countPrintn(n);
if (width > 0 && !negFlag) {
fill(width - count, filler);
}
printn(n);
if (width > 0 && negFlag) {
fill(width - count, filler);
}
} else
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
u = va_arg(ap, int);
count = countPrintu(u,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
if (width > 0 && !negFlag) {
fill(width - count, filler);
}
printu(u,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
c == 'X');
if (width > 0 && negFlag) {
fill(width - count, filler);
}
} else
if (c == 'l') {
c = *fmt++;
if (c == 'd') {
ln = va_arg(ap, long);
count = countPrintn(ln);
if (width > 0 && !negFlag) {
fill(width - count, filler);
}
printn(ln);
if (width > 0 && negFlag) {
fill(width - count, filler);
}
} else
if (c == 'u' || c == 'o' || c == 'x' || c == 'X') {
lu = va_arg(ap, long);
count = countPrintu(lu,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10));
if (width > 0 && !negFlag) {
fill(width - count, filler);
}
printu(lu,
c == 'o' ? 8 : ((c == 'x' || c == 'X') ? 16 : 10),
c == 'X');
if (width > 0 && negFlag) {
fill(width - count, filler);
}
} else {
putchar('l');
putchar(c);
}
} else
if (c == 's') {
s = va_arg(ap, char *);
count = strlen(s);
if (width > 0 && !negFlag) {
fill(width - count, filler);
}
while ((c = *s++) != '\0') {
putchar(c);
}
if (width > 0 && negFlag) {
fill(width - count, filler);
}
} else
if (c == 'c') {
c = va_arg(ap, char);
putchar(c);
} else {
putchar(c);
}
}
}
 
 
/*
* Formatted output.
* This is a scaled-down version of the C library's
* printf. Used to print diagnostic information on
* the console (and optionally to a logfile).
*/
void printf(char *fmt, ...) {
va_list ap;
 
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
/stdalone/dmpmbr/biolib.c
0,0 → 1,26
/*
* biolib.c -- basic I/O library
*/
 
 
#include "biolib.h"
 
 
char getc(void) {
unsigned int *base;
char c;
 
base = (unsigned int *) 0xF0300000;
while ((*(base + 0) & 1) == 0) ;
c = *(base + 1);
return c;
}
 
 
void putc(char c) {
unsigned int *base;
 
base = (unsigned int *) 0xF0300000;
while ((*(base + 2) & 1) == 0) ;
*(base + 3) = c;
}
/stdalone/dmpmbr/start.h
0,0 → 1,21
/*
* start.h -- startup code
*/
 
 
#ifndef _START_H_
#define _START_H_
 
 
typedef int (*ISR)(int irq);
 
 
void enable(void);
void disable(void);
int getMask(void);
void setMask(int mask);
ISR getISR(int irq);
void setISR(int irq, ISR isr);
 
 
#endif /* _START_H_ */
/stdalone/dmpmbr/iolib.h
0,0 → 1,21
/*
* iolib.h -- I/O library
*/
 
 
#ifndef _IOLIB_H_
#define _IOLIB_H_
 
 
int strlen(char *str);
void strcpy(char *dst, char *src);
void memcpy(unsigned char *dst, unsigned char *src, unsigned int cnt);
char getchar(void);
void putchar(char c);
void putString(char *s);
void getLine(char *prompt, char *line, int max);
void vprintf(char *fmt, va_list ap);
void printf(char *fmt, ...);
 
 
#endif /* _IOLIB_H_ */
/stdalone/dmpmbr/main.c
0,0 → 1,184
/*
* main.c -- dump the master boot record of a disk
*/
 
 
#include "types.h"
#include "stdarg.h"
#include "iolib.h"
#include "start.h"
#include "idedsk.h"
 
 
/**************************************************************/
 
 
void error(char *fmt, ...) {
va_list ap;
 
va_start(ap, fmt);
printf("Error: ");
vprintf(fmt, ap);
printf(", halting...\n");
va_end(ap);
while (1) ;
}
 
 
/**************************************************************/
 
 
static char *exceptionCause[32] = {
/* 00 */ "terminal 0 transmitter interrupt",
/* 01 */ "terminal 0 receiver interrupt",
/* 02 */ "terminal 1 transmitter interrupt",
/* 03 */ "terminal 1 receiver interrupt",
/* 04 */ "keyboard interrupt",
/* 05 */ "unknown interrupt",
/* 06 */ "unknown interrupt",
/* 07 */ "unknown interrupt",
/* 08 */ "disk interrupt",
/* 09 */ "unknown interrupt",
/* 10 */ "unknown interrupt",
/* 11 */ "unknown interrupt",
/* 12 */ "unknown interrupt",
/* 13 */ "unknown interrupt",
/* 14 */ "timer 0 interrupt",
/* 15 */ "timer 1 interrupt",
/* 16 */ "bus timeout exception",
/* 17 */ "illegal instruction exception",
/* 18 */ "privileged instruction exception",
/* 19 */ "divide instruction exception",
/* 20 */ "trap instruction exception",
/* 21 */ "TLB miss exception",
/* 22 */ "TLB write exception",
/* 23 */ "TLB invalid exception",
/* 24 */ "illegal address exception",
/* 25 */ "privileged address exception",
/* 26 */ "unknown exception",
/* 27 */ "unknown exception",
/* 28 */ "unknown exception",
/* 29 */ "unknown exception",
/* 30 */ "unknown exception",
/* 31 */ "unknown exception"
};
 
 
int defaultISR(int irq) {
printf("\n%s\n", exceptionCause[irq]);
return 0; /* do not skip any instruction */
}
 
 
void initInterrupts(void) {
int i;
 
for (i = 0; i < 32; i++) {
setISR(i, defaultISR);
}
}
 
 
/**************************************************************/
 
 
Bool checkDiskReady(void) {
int tries;
int i;
 
for (tries = 0; tries < 10; tries++) {
for (i = 0; i < 500000; i++) {
if ((*DISK_CTRL & DISK_CTRL_READY) != 0) {
return TRUE;
}
}
printf(".");
}
return FALSE;
}
 
 
unsigned long getDiskSize(void) {
return *DISK_CAP;
}
 
 
Bool readDisk(unsigned long sector,
unsigned int count,
unsigned int *addr) {
unsigned int n;
unsigned int *p;
unsigned int i;
 
while (count != 0) {
n = count > 8 ? 8 : count;
*DISK_SCT = sector;
*DISK_CNT = n;
*DISK_CTRL = DISK_CTRL_STRT;
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
if (*DISK_CTRL & DISK_CTRL_ERR) {
return FALSE;
}
p = DISK_BUFFER;
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
*addr++ = *p++;
}
sector += n;
count -= n;
}
return TRUE;
}
 
 
/**************************************************************/
 
 
void main(void) {
unsigned long numSectors;
unsigned int buffer[SECTOR_SIZE / sizeof(unsigned int)];
int i, j;
unsigned char *p, *q;
unsigned char c;
 
/* init interrupts */
initInterrupts();
/* check disk ready */
if (!checkDiskReady()) {
error("disk not ready");
}
/* determine disk size */
numSectors = getDiskSize();
printf("Disk has %lu (0x%lX) sectors.\n",
numSectors, numSectors);
if (numSectors < 32) {
error("disk is too small");
}
/* read master boot record */
if (!readDisk(0, 1, buffer)) {
error("cannot read master boot record from disk");
}
/* dump master boot record */
p = (unsigned char *) buffer;
for (i = 0; i < 32; i++) {
printf("%08X: ", i * 16);
q = p;
for (j = 0; j < 16; j++) {
c = *q++;
printf("%02X ", c);
}
printf(" ");
q = p;
for (j = 0; j < 16; j++) {
c = *q++;
if (c >= 32 && c <= 126) {
printf("%c", c);
} else {
printf(".");
}
}
printf("\n");
p = q;
}
/* done */
printf("Halting...\n");
}
/stdalone/dmpmbr/biolib.h
0,0 → 1,14
/*
* biolib.h -- basic I/O library
*/
 
 
#ifndef _BIOLIB_H_
#define _BIOLIB_H_
 
 
char getc(void);
void putc(char c);
 
 
#endif /* _BIOLIB_H_ */
/stdalone/dmpmbr/end.s
0,0 → 1,19
;
; end.s -- end-of-segment labels
;
 
.export _ecode
.export _edata
.export _ebss
 
.code
.align 4
_ecode:
 
.data
.align 4
_edata:
 
.bss
.align 4
_ebss:
/stdalone/dmpmbr/idedsk.h
0,0 → 1,32
/*
* idedsk.h -- IDE disk definitions
*/
 
 
#ifndef _IDEDSK_H_
#define _IDEDSK_H_
 
 
#define SECTOR_SIZE 512
#define WPS (SECTOR_SIZE / sizeof(unsigned int))
 
#define DISK_BASE ((unsigned *) 0xF0400000) /* disk base address */
#define DISK_CTRL (DISK_BASE + 0) /* control/status register */
#define DISK_CNT (DISK_BASE + 1) /* sector count register */
#define DISK_SCT (DISK_BASE + 2) /* disk sector register */
#define DISK_CAP (DISK_BASE + 3) /* disk capacity register */
#define DISK_BUFFER ((unsigned *) 0xF0480000) /* address of disk buffer */
 
#define DISK_CTRL_STRT 0x01 /* a 1 written here starts the disk command */
#define DISK_CTRL_IEN 0x02 /* enable disk interrupt */
#define DISK_CTRL_WRT 0x04 /* command type: 0 = read, 1 = write */
#define DISK_CTRL_ERR 0x08 /* 0 = ok, 1 = error; valid when DONE = 1 */
#define DISK_CTRL_DONE 0x10 /* 1 = disk has finished the command */
#define DISK_CTRL_READY 0x20 /* 1 = capacity valid, disk accepts command */
 
#define DISK_IRQ 8 /* disk interrupt number */
 
#define READY_RETRIES 1000000 /* retries to wait for disk to get ready */
 
 
#endif /* _IDEDSK_H_ */
/stdalone/dmpmbr/stdarg.h
0,0 → 1,41
/*
* stdarg.h -- variable argument lists
*/
 
 
#ifndef _STDARG_H_
#define _STDARG_H_
 
 
typedef char *va_list;
 
 
static float __va_arg_tmp;
 
 
#define va_start(list, start) \
((void)((list) = (sizeof(start)<4 ? \
(char *)((int *)&(start)+1) : (char *)(&(start)+1))))
 
#define __va_arg(list, mode, n) \
(__typecode(mode)==1 && sizeof(mode)==4 ? \
(__va_arg_tmp = *(double *)(&(list += \
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \
*(mode *)&__va_arg_tmp) : \
*(mode *)(&(list += \
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)]))
 
#define _bigendian_va_arg(list, mode, n) \
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \
__va_arg(list, mode, n))
 
#define va_end(list) ((void)0)
 
#define va_arg(list, mode) \
(sizeof(mode)==8 ? \
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \
_bigendian_va_arg(list, mode, 3U))
 
 
#endif /* _STDARG_H_ */
/stdalone/dmpmbr/types.h
0,0 → 1,16
/*
* types.h -- additional types
*/
 
 
#ifndef _TYPES_H_
#define _TYPES_H_
 
 
typedef int Bool;
 
#define FALSE 0
#define TRUE 1
 
 
#endif /* _TYPES_H_ */
/stdalone/dmpmbr/Makefile
0,0 → 1,34
#
# Makefile for "dmpmbr", a program to dump the master boot record of a disk
#
 
BUILD = ../../build
 
SRC = start.s main.c iolib.c biolib.c end.s
BIN = dmpmbr.bin
MAP = dmpmbr.map
EXO = dmpmbr.exo
 
.PHONY: all install run clean
 
all: $(BIN) $(EXO)
 
install: $(BIN) $(EXO)
mkdir -p $(BUILD)/stdalone
cp $(BIN) $(BUILD)/stdalone
cp $(MAP) $(BUILD)/stdalone
cp $(EXO) $(BUILD)/stdalone
 
run: $(BIN)
$(BUILD)/bin/sim -i -t 1 -l $(BIN) -a 0x10000 \
-d $(BUILD)/run/disk.img
 
$(EXO): $(BIN)
$(BUILD)/bin/bin2exo -S2 0x10000 $(BIN) $(EXO)
 
$(BIN): $(SRC)
$(BUILD)/bin/lcc -A -Wo-kernel \
-Wl-m -Wl$(MAP) -o $(BIN) $(SRC)
 
clean:
rm -f *~ $(BIN) $(MAP) $(EXO)
/stdalone/dmpmbr/start.s
0,0 → 1,233
;
; start.s -- startup code
;
 
.import main
.import _ecode
.import _edata
.import _ebss
 
.export _bcode
.export _bdata
.export _bbss
 
.export enable
.export disable
.export getMask
.export setMask
.export getISR
.export setISR
 
.code
_bcode:
 
.data
_bdata:
 
.bss
_bbss:
 
.code
 
; reset arrives here
reset:
j start
 
; interrupts arrive here
intrpt:
j isr
 
; user TLB misses arrive here
userMiss:
j userMiss
 
isr:
add $26,$29,$0 ; sp -> $26
add $27,$1,$0 ; $1 -> $27
add $29,$0,istack ; set stack
sub $29,$29,108
stw $2,$29,0 ; save registers
stw $3,$29,4
stw $4,$29,8
stw $5,$29,12
stw $6,$29,16
stw $7,$29,20
stw $8,$29,24
stw $9,$29,28
stw $10,$29,32
stw $11,$29,36
stw $12,$29,40
stw $13,$29,44
stw $14,$29,48
stw $15,$29,52
stw $16,$29,56
stw $17,$29,60
stw $18,$29,64
stw $19,$29,68
stw $20,$29,72
stw $21,$29,76
stw $22,$29,80
stw $23,$29,84
stw $24,$29,88
stw $25,$29,92
stw $26,$29,96
stw $27,$29,100
stw $31,$29,104
mvfs $4,0 ; $4 = IRQ number
slr $4,$4,16
and $4,$4,0x1F
sll $26,$4,2 ; $26 = 4 * IRQ number
ldw $26,$26,irqsrv ; get addr of service routine
jalr $26 ; call service routine
beq $2,$0,resume ; resume instruction if ISR returned 0
add $30,$30,4 ; else skip offending instruction
resume:
ldw $2,$29,0
ldw $3,$29,4
ldw $4,$29,8
ldw $5,$29,12
ldw $6,$29,16
ldw $7,$29,20
ldw $8,$29,24
ldw $9,$29,28
ldw $10,$29,32
ldw $11,$29,36
ldw $12,$29,40
ldw $13,$29,44
ldw $14,$29,48
ldw $15,$29,52
ldw $16,$29,56
ldw $17,$29,60
ldw $18,$29,64
ldw $19,$29,68
ldw $20,$29,72
ldw $21,$29,76
ldw $22,$29,80
ldw $23,$29,84
ldw $24,$29,88
ldw $25,$29,92
ldw $26,$29,96
ldw $27,$29,100
ldw $31,$29,104
add $1,$27,$0 ; $27 -> $1
add $29,$26,0 ; $26 -> sp
rfx ; return from exception
 
start:
add $8,$0,0xA8003FFF
add $9,$0,0xC0000000
stw $8,$9,0 ; 0xC0000000: j 0xC0010000
stw $8,$9,4 ; 0xC0000004: j 0xC0010004
stw $8,$9,8 ; 0xC0000008: j 0xC0010008
mvfs $8,0
or $8,$8,1 << 27 ; let vector point to RAM
mvts $8,0
add $29,$0,stack ; set sp
add $10,$0,_bdata ; copy data segment
add $8,$0,_edata
sub $9,$8,$10
add $9,$9,_ecode
j cpytest
cpyloop:
ldw $11,$9,0
stw $11,$8,0
cpytest:
sub $8,$8,4
sub $9,$9,4
bgeu $8,$10,cpyloop
add $8,$0,_bbss ; clear bss
add $9,$0,_ebss
j clrtest
clrloop:
stw $0,$8,0
add $8,$8,4
clrtest:
bltu $8,$9,clrloop
jal main ; call 'main'
start1:
j start1 ; loop
 
enable:
mvfs $8,0
or $8,$8,1 << 23
mvts $8,0
jr $31
 
disable:
mvfs $8,0
and $8,$8,~(1 << 23)
mvts $8,0
jr $31
 
getMask:
mvfs $8,0
and $2,$8,0x0000FFFF
jr $31
 
setMask:
mvfs $8,0
and $8,$8,0xFFFF0000
and $4,$4,0x0000FFFF
or $8,$8,$4
mvts $8,0
jr $31
 
getISR:
sll $4,$4,2
ldw $2,$4,irqsrv
jr $31
 
setISR:
sll $4,$4,2
stw $5,$4,irqsrv
jr $31
 
.data
 
; interrupt service routine table
 
.align 4
 
irqsrv:
.word 0 ; 00: terminal 0 transmitter interrupt
.word 0 ; 01: terminal 0 receiver interrupt
.word 0 ; 02: terminal 1 transmitter interrupt
.word 0 ; 03: terminal 1 receiver interrupt
.word 0 ; 04: keyboard interrupt
.word 0 ; 05: unused
.word 0 ; 06: unused
.word 0 ; 07: unused
.word 0 ; 08: disk interrupt
.word 0 ; 09: unused
.word 0 ; 10: unused
.word 0 ; 11: unused
.word 0 ; 12: unused
.word 0 ; 13: unused
.word 0 ; 14: timer 0 interrupt
.word 0 ; 15: timer 1 interrupt
.word 0 ; 16: bus timeout exception
.word 0 ; 17: illegal instruction exception
.word 0 ; 18: privileged instruction exception
.word 0 ; 19: divide instruction exception
.word 0 ; 20: trap instruction exception
.word 0 ; 21: TLB miss exception
.word 0 ; 22: TLB write exception
.word 0 ; 23: TLB invalid exception
.word 0 ; 24: illegal address exception
.word 0 ; 25: privileged address exception
.word 0 ; 26: unused
.word 0 ; 27: unused
.word 0 ; 28: unused
.word 0 ; 29: unused
.word 0 ; 30: unused
.word 0 ; 31: unused
 
.bss
 
.align 4
.space 0x800
stack:
 
.align 4
.space 0x800
istack:
/stdalone/Makefile
6,7 → 6,7
BUILD = ../build
 
DIRS = hello hello2 memsize onetask twotasks-1 twotasks-2 \
wrtmbr dskchk mkpart shpart
wrtmbr dmpmbr dskchk mkpart shpart
 
.PHONY: all install clean
 

powered by: WebSVN 2.1.0

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