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

Subversion Repositories eco32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /eco32/tags/eco32-0.23/stdalone/mkpart
    from Rev 108 to Rev 157
    Reverse comparison

Rev 108 → Rev 157

/Makefile
0,0 → 1,55
#
# Makefile for "mkpart", a program to write the partition table
# and the bootblock on a hard disk
#
 
BUILD = ../../build
 
SRC = start.s main.c iolib.c biolib.c end.s
BIN = mkpart.bin
MAP = mkpart.map
EXO = mkpart.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) mboot.dump
$(BUILD)/bin/lcc -A -Wo-kernel \
-Wl-m -Wl$(MAP) -o $(BIN) $(SRC)
 
mboot.dump: dump/dump mboot
./dump/dump mboot mboot.dump
 
dump/dump:
$(MAKE) -C dump all
 
mboot: mkmboot/mbootblk mkptbl/parttbl
dd if=/dev/zero of=mboot bs=512 count=32
dd if=mkmboot/mbootblk of=mboot bs=512 conv=notrunc
dd if=mkptbl/parttbl of=mboot bs=512 seek=1 conv=notrunc
 
mkptbl/parttbl:
$(MAKE) -C mkptbl all
 
mkmboot/mbootblk:
$(MAKE) -C mkmboot all
 
clean:
$(MAKE) -C dump clean
$(MAKE) -C mkptbl clean
$(MAKE) -C mkmboot clean
rm -f *~ mboot mboot.dump $(BIN) $(MAP) $(EXO)
/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:
/mkmboot/stage1/mbr.s
0,0 → 1,111
;
; mbr.s -- the master boot record
;
 
; Runtime environment:
;
; This code must be loaded and started at 0xC0010000.
; It allocates a stack from 0xC0011000 downwards. So
; it must run within 4K (code + data + stack).
;
; This code expects the disk number of the boot disk
; in $16, the start sector of the disk or partition
; to be booted in $17 and its size in $18.
;
; The boot manager, which is loaded by this code,
; must be in standalone (headerless) executable
; format, stored at absolute disk sectors 2..31,
; and gets loaded and started at 0xC0011000.
 
.set stacktop,0xC0011000 ; top of stack
.set loadaddr,0xC0011000 ; where to load the boot manager
 
.set cout,0xC0000018 ; the monitor's console output
.set dskio,0xC0000030 ; the monitor's disk I/O
 
; load the boot manager and start it
start:
add $29,$0,stacktop ; setup stack
add $4,$0,strtmsg ; say what is going on
jal msgout
add $4,$0,2 ; start loading with sector 2
add $5,$0,loadaddr ; where to load the boot manager
and $5,$5,0x3FFFFFFF ; convert to physical address
add $6,$0,30 ; 30 sectors to load
jal rdsct
add $8,$0,loadaddr ; start executing the boot manager
jr $8
 
; read disk sectors
; $4 start sector number (disk or partition relative)
; $5 transfer address
; $6 number of sectors
rdsct:
sub $29,$29,32
stw $31,$29,20
stw $6,$29,16 ; sector count
add $7,$5,$0 ; transfer address
add $6,$4,$17 ; relative sector -> absolute
add $5,$0,'r' ; command
add $4,$0,$16 ; disk number
add $8,$0,dskio
jalr $8
bne $2,$0,rderr ; error?
ldw $31,$29,20
add $29,$29,32
jr $31
 
; disk read error
rderr:
add $4,$0,dremsg
jal msgout
j halt
 
; output message
; $4 pointer to string
msgout:
sub $29,$29,8
stw $31,$29,4
stw $16,$29,0
add $16,$4,0 ; $16: pointer to string
msgout1:
ldbu $4,$16,0 ; get character
beq $4,$0,msgout2 ; done?
jal chrout ; output character
add $16,$16,1 ; bump pointer
j msgout1 ; continue
msgout2:
ldw $16,$29,0
ldw $31,$29,4
add $29,$29,8
jr $31
 
; output character
; $4 character
chrout:
sub $29,$29,4
stw $31,$29,0
add $8,$0,cout
jalr $8
ldw $31,$29,0
add $29,$29,4
jr $31
 
; halt execution by looping
halt:
add $4,$0,hltmsg
jal msgout
halt1:
j halt1
 
; messages
strtmsg:
.byte "MBR executing...", 0x0D, 0x0A, 0
dremsg:
.byte "disk read error", 0x0D, 0x0A, 0
hltmsg:
.byte "bootstrap halted", 0x0D, 0x0A, 0
 
; boot record signature
.locate 512-2
.byte 0x55, 0xAA
/mkmboot/stage1/Makefile
0,0 → 1,16
#
# Makefile to build the master boot record
#
 
BUILD = ../../../../build
 
all: mbr.bin
 
mbr.bin: mbr.o
$(BUILD)/bin/ld -h -rc 0xC0010000 -o mbr.bin mbr.o
 
mbr.o: mbr.s
$(BUILD)/bin/as -o mbr.o mbr.s
 
clean:
rm -f *~ mbr.o mbr.bin
/mkmboot/Makefile
0,0 → 1,24
#
# Makefile to build the master boot block (with an empty partition table)
#
 
BUILD = ../../../build
 
.PHONY: all clean
 
all: mbootblk
 
mbootblk: stage1/mbr.bin stage2/mboot.bin
dd if=/dev/zero of=./zeroes bs=512 count=1
cat stage1/mbr.bin zeroes stage2/mboot.bin >mbootblk
 
stage1/mbr.bin:
$(MAKE) -C stage1
 
stage2/mboot.bin:
$(MAKE) -C stage2
 
clean:
$(MAKE) -C stage1 clean
$(MAKE) -C stage2 clean
rm -f *~ zeroes mbootblk
/mkmboot/stage2/biolib.s
0,0 → 1,26
;
; biolib.s -- basic I/O library
;
 
.set cin,0xC0000010
.set cout,0xC0000018
.set dskio,0xC0000030
 
.export getc
.export putc
.export rwscts
 
.code
.align 4
 
getc:
add $8,$0,cin
jr $8
 
putc:
add $8,$0,cout
jr $8
 
rwscts:
add $8,$0,dskio
jr $8
/mkmboot/stage2/mboot.c
0,0 → 1,273
/*
* mboot.c -- the master bootstrap (boot manager)
*/
 
 
#include "stdarg.h"
#include "biolib.h"
 
 
#define DEFAULT_PARTITION "" /* default boot partition number */
 
#define LOAD_ADDR 0xC0010000
 
#define LINE_SIZE 80
#define SECTOR_SIZE 512
#define NPE (SECTOR_SIZE / sizeof(PartEntry))
#define DESCR_SIZE 20
 
 
unsigned int bootDisk = 0; /* gets loaded by previous stage */
unsigned int startSector = 0; /* gets loaded by previous stage */
unsigned int numSectors = 0; /* gets loaded by previous stage */
 
 
typedef struct {
unsigned long type;
unsigned long start;
unsigned long size;
char descr[DESCR_SIZE];
} PartEntry;
 
PartEntry ptr[NPE];
 
 
int strlen(char *str) {
int i;
 
i = 0;
while (*str++ != '\0') {
i++;
}
return i;
}
 
 
void strcpy(char *dst, char *src) {
while ((*dst++ = *src++) != '\0') ;
}
 
 
char getchar(void) {
return getc();
}
 
 
void putchar(char c) {
if (c == '\n') {
putchar('\r');
}
putc(c);
}
 
 
void puts(char *s) {
char c;
 
while ((c = *s++) != '\0') {
putchar(c);
}
}
 
 
void getline(char *prompt, char *line, int n) {
int i;
char c;
 
puts(prompt);
puts(line);
i = strlen(line);
while (i < n - 1) {
c = getchar();
if (c >= ' ' && c < 0x7F) {
putchar(c);
line[i] = c;
i++;
} else
if (c == '\r') {
putchar('\n');
line[i] = '\0';
i = n - 1;
} else
if (c == '\b' || c == 0x7F) {
if (i > 0) {
putchar('\b');
putchar(' ');
putchar('\b');
i--;
}
}
}
line[n - 1] = '\0';
}
 
 
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;
}
 
 
void printn(long n) {
long a;
 
if (n < 0) {
putchar('-');
n = -n;
}
a = n / 10;
if (a != 0) {
printn(a);
}
putchar(n % 10 + '0');
}
 
 
void printf(char *fmt, ...) {
va_list ap;
char c;
int n;
unsigned int u;
char *s;
char filler;
int width, count, i;
 
va_start(ap, fmt);
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
va_end(ap);
return;
}
putchar(c);
}
c = *fmt++;
if (c == '0') {
filler = '0';
c = *fmt++;
} else {
filler = ' ';
}
width = 0;
if (c >= '0' && c <= '9') {
width = c - '0';
c = *fmt++;
}
if (c == 'd') {
n = va_arg(ap, int);
if (width > 0) {
count = countPrintn(n);
for (i = 0; i < width - count; i++) {
putchar(filler);
}
}
printn(n);
} else
if (c == 's') {
s = va_arg(ap, char *);
puts(s);
} else
if (c == 'c') {
c = va_arg(ap, char);
putchar(c);
} else {
putchar(c);
}
}
}
 
 
void halt(void) {
printf("bootstrap halted\n");
while (1) ;
}
 
 
void readDisk(unsigned int sector, unsigned char *buffer, int count) {
int result;
 
if (sector + count > numSectors) {
printf("sector number exceeds disk or partition size\n");
halt();
}
result = rwscts(bootDisk, 'r', sector + startSector,
(unsigned int) buffer & 0x3FFFFFFF, count);
if (result != 0) {
printf("disk read error\n");
halt();
}
}
 
 
unsigned int entryPoint; /* where to continue from main() */
 
 
int main(void) {
int i;
char line[LINE_SIZE];
char *p;
int part;
 
printf("Bootstrap manager executing...\n");
strcpy(line, DEFAULT_PARTITION);
readDisk(1, (unsigned char *) ptr, 1);
while (1) {
printf("\nPartitions:\n");
printf(" # | b | description\n");
printf("---+---+----------------------\n");
for (i = 0; i < NPE; i++) {
if (ptr[i].type != 0) {
printf("%2d | %s | %s\n",
i, ptr[i].type & 0x80000000 ? "*" : " ", ptr[i].descr);
}
}
getline("\nBoot partition #: ", line, LINE_SIZE);
part = 0;
if (line[0] == '\0') {
continue;
}
p = line;
while (*p >= '0' && *p <= '9') {
part = part * 10 + (*p - '0');
p++;
}
if (*p != '\0' || part < 0 || part > 15) {
printf("illegal partition number\n");
continue;
}
if ((ptr[part].type & 0x7FFFFFFF) == 0) {
printf("partition %d does not contain a file system\n", part);
continue;
}
if ((ptr[part].type & 0x80000000) == 0) {
printf("partition %d is not bootable\n", part);
continue;
}
/* load boot sector of selected partition */
readDisk(ptr[part].start, (unsigned char *) LOAD_ADDR, 1);
/* check for signature */
if ((*((unsigned char *) LOAD_ADDR + SECTOR_SIZE - 2) != 0x55) ||
(*((unsigned char *) LOAD_ADDR + SECTOR_SIZE - 1) != 0xAA)) {
printf("boot sector of partition %d has no signature\n", part);
continue;
}
/* we have a valid boot sector, leave loop */
break;
}
/* boot manager finished, now go executing loaded boot sector */
startSector = ptr[part].start;
numSectors = ptr[part].size;
entryPoint = LOAD_ADDR;
return 0;
}
/mkmboot/stage2/c0.s
0,0 → 1,59
;
; c0.s -- startup code and begin-of-segment labels
;
 
.import main
 
.import _ecode
.import _edata
.import _ebss
 
.export _bcode
.export _bdata
.export _bbss
 
.import bootDisk
.import startSector
.import numSectors
.import entryPoint
 
.code
_bcode:
 
start:
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 segment
add $9,$0,_ebss
j clrtest
clrloop:
stw $0,$8,0
add $8,$8,4
clrtest:
bltu $8,$9,clrloop
add $29,$0,0xC0020000 ; setup stack
stw $16,$0,bootDisk ; make arguments available
stw $17,$0,startSector
stw $18,$0,numSectors
jal main ; call 'main' function
ldw $16,$0,bootDisk ; setup arguments for next stage
ldw $17,$0,startSector
ldw $18,$0,numSectors
ldw $31,$0,entryPoint ; jump to loaded program
jr $31
 
.data
_bdata:
 
.bss
_bbss:
/mkmboot/stage2/biolib.h
0,0 → 1,15
/*
* biolib.h -- basic I/O library
*/
 
 
#ifndef _BIOLIB_H_
#define _BIOLIB_H_
 
 
char getc(void);
void putc(char c);
int rwscts(int dskno, int cmd, int sector, int addr, int count);
 
 
#endif /* _BIOLIB_H_ */
/mkmboot/stage2/Makefile
0,0 → 1,26
#
# Makefile to build the master bootstrap (boot manager)
#
 
BUILD = ../../../../build
 
all: mboot.bin
 
mboot.bin: c0.o mboot.o biolib.o c1.o
$(BUILD)/bin/ld -h -rc 0xC0011000 -o mboot.bin \
c0.o mboot.o biolib.o c1.o
 
c0.o: c0.s
$(BUILD)/bin/as -o c0.o c0.s
 
mboot.o: mboot.c
$(BUILD)/bin/lcc -A -c -o mboot.o mboot.c
 
biolib.o: biolib.s
$(BUILD)/bin/as -o biolib.o biolib.s
 
c1.o: c1.s
$(BUILD)/bin/as -o c1.o c1.s
 
clean:
rm -f *~ c0.o mboot.o biolib.o c1.o mboot.bin
/mkmboot/stage2/c1.s
0,0 → 1,19
;
; c1.s -- end-of-segment labels
;
 
.export _ecode
.export _edata
.export _ebss
 
.code
.align 4
_ecode:
 
.data
.align 4
_edata:
 
.bss
.align 4
_ebss:
/mkmboot/stage2/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_ */
/main.c
0,0 → 1,222
/*
* main.c -- program to write the partition table
* and the bootblock on a hard 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) ;
}
 
 
/**************************************************************/
 
 
/*
* the boot block byte array need not be word-aligned
*/
unsigned char mboot[32 * SECTOR_SIZE] = {
#include "mboot.dump"
};
 
 
/*
* the write buffer must be word-aligned
*/
unsigned int wrBuf[32 * SECTOR_SIZE / sizeof(unsigned int)];
 
 
/*
* copy byte array to write buffer
*/
void copyBootBlock(void) {
unsigned char *p;
unsigned char *q;
int i;
 
p = (unsigned char *) wrBuf;
q = (unsigned char *) mboot;
for (i = 0; i < 32 * SECTOR_SIZE; i++) {
*p++ = *q++;
}
}
 
 
/**************************************************************/
 
 
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;
}
 
 
Bool writeDisk(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;
p = DISK_BUFFER;
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
*p++ = *addr++;
}
*DISK_SCT = sector;
*DISK_CNT = n;
*DISK_CTRL = DISK_CTRL_WRT | DISK_CTRL_STRT;
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
if (*DISK_CTRL & DISK_CTRL_ERR) {
return FALSE;
}
sector += n;
count -= n;
}
return TRUE;
}
 
 
/**************************************************************/
 
 
void main(void) {
unsigned long numSectors;
 
/* 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");
}
/* copy boot block to write buffer */
copyBootBlock();
/* write boot block to disk */
printf("Writing boot block to disk...\n");
if (!writeDisk(0, 32, wrBuf)) {
error("cannot write boot block to disk");
}
/* done */
printf("Halting...\n");
}
/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);
}
/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;
}
/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_ */
/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_ */
/dump/dump.c
0,0 → 1,48
/*
* dump.c -- dump a binary file as contents of a C array
*/
 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
 
int main(int argc, char *argv[]) {
FILE *infile, *outfile;
int c, n;
 
if (argc != 3) {
printf("Usage: %s <infile> <outfile>\n", argv[0]);
return 1;
}
infile = fopen(argv[1], "rb");
if (infile == NULL) {
printf("Error: cannot open file '%s' for input\n", argv[1]);
return 1;
}
outfile = fopen(argv[2], "wt");
if (outfile == NULL) {
printf("Error: cannot open file '%s' for output\n", argv[2]);
return 1;
}
n = 0;
while (1) {
c = getc(infile);
if (c == EOF) {
break;
}
fprintf(outfile, "0x%02X, ", c);
n++;
if (n == 8) {
n = 0;
fprintf(outfile, "\n");
}
}
if (n != 0) {
fprintf(outfile, "\n");
}
fclose(infile);
fclose(outfile);
return 0;
}
/dump/Makefile
0,0 → 1,15
#
# Makefile for dump utility
#
 
.PHONY: all install clean
 
all: dump
 
install: dump
 
dump: dump.c
gcc -m32 -g -Wall -o dump dump.c
 
clean:
rm -f *~ dump
/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_ */
/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:
/mkptbl/disk.part
0,0 → 1,41
#
# disk.part -- disk partitioning configuration file
#
 
# This file consists of partition table entries, one per line
# (empty or comment lines are also allowed). Each entry is in
# the following form:
#
# partition boot type start last description
#
# partition:
# possible values 0..15
# indicates partition number
# different entries need not be sorted in any way
# no two entries may have the same partition number
# boot:
# '*' means that the partition can be booted
# leave this blank if the partition cannot be booted
# more than one partition may be bootable
# type:
# possible values 0..0x7FFFFFFF
# indicates partition type
# 0x0000 = partition table entry not used
# 0x0058 = EOS32 file system partition
# 0x0059 = EOS32 swap space partition
# 0x00A9 = NetBSD partition
# start:
# sector number where partition starts (0-based)
# no partition may start below sector 32
# last:
# last sector of partition (0-based)
# partitions must not overlap
# description:
# max. 512 / 16 - 12 = 20 characters (includes trailing 0)
# this may be displayed during bootstrap
 
0 * 0x0058 32 131071 "EOS32 root"
1 0x0058 131072 393215 "EOS32 usr"
2 0x0059 393216 524287 "EOS32 swap"
3 0x0058 524288 1048575 "EOS32 home"
4 * 0x00A9 2097152 33554431 "NetBSD 6.0"
/mkptbl/mkptbl.c
0,0 → 1,275
/*
* mkptbl.c -- make partition table
*/
 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
 
 
#define SECTOR_SIZE 512
#define NPE (SECTOR_SIZE / sizeof(PartEntry))
#define DESCR_SIZE 20
 
#define LINE_SIZE 100
 
 
typedef struct {
unsigned long type;
unsigned long start;
unsigned long size;
char descr[DESCR_SIZE];
} PartEntry;
 
PartEntry ptr[NPE];
 
 
void error(char *fmt, ...) {
va_list ap;
 
va_start(ap, fmt);
printf("Error: ");
vprintf(fmt, ap);
printf("\n");
va_end(ap);
exit(1);
}
 
 
void convertNumber(unsigned char *p, unsigned long val) {
*(p + 0) = val >> 24;
*(p + 1) = val >> 16;
*(p + 2) = val >> 8;
*(p + 3) = val >> 0;
}
 
 
void convertPartitionTable(PartEntry *e, int n) {
int i;
unsigned char *p;
 
for (i = 0; i < n; i++) {
p = (unsigned char *) &e[i];
convertNumber(p + 0, e[i].type);
convertNumber(p + 4, e[i].start);
convertNumber(p + 8, e[i].size);
}
}
 
 
int parseNumber(char **pc, unsigned long *pi) {
char *p;
unsigned int base, dval;
unsigned long n;
 
p = *pc;
while (*p == ' ' || *p == '\t') {
p++;
}
if (*p == '\0' || *p == '\n') {
printf("Error: number is missing!\n");
return 0;
}
base = 10;
if (*p == '0') {
p++;
if (*p != '\0' && *p != '\n') {
if (*p == 'x' || *p == 'X') {
base = 16;
p++;
} else {
base = 8;
}
}
}
n = 0;
while ((*p >= '0' && *p <= '9') ||
(*p >= 'a' && *p <= 'f') ||
(*p >= 'A' && *p <= 'F')) {
if (*p >= '0' && *p <= '9') {
dval = (*p - '0');
} else
if (*p >= 'a' && *p <= 'f') {
dval = (*p - 'a' + 10);
} else
if (*p >= 'A' && *p <= 'F') {
dval = (*p - 'A' + 10);
}
if (dval >= base) {
printf("Error: digit value %d is illegal in number base %d\n",
dval, base);
return 0;
}
n *= base;
n += dval;
p++;
}
while (*p == ' ' || *p == '\t') {
p++;
}
*pc = p;
*pi = n;
return 1;
}
 
 
int parseString(char **pc, char *dst) {
char *p;
 
p = *pc;
while (*p == ' ' || *p == '\t') {
p++;
}
if (*p != '\"') {
return 0;
}
p++;
while (*p != '\"' && *p != '\0' && *p != '\n') {
*dst++ = *p++;
}
if (*p != '\"') {
return 0;
}
p++;
while (*p == ' ' || *p == '\t') {
p++;
}
*pc = p;
*dst = '\0';
return 1;
}
 
 
int main(int argc, char *argv[]) {
char *confName;
char *outName;
FILE *conf;
FILE *out;
char line[LINE_SIZE];
char *p;
int lineNumber;
unsigned long partNum;
unsigned long bootable;
unsigned long partType;
unsigned long partStart;
unsigned long partLast;
unsigned long partSize;
char descr[LINE_SIZE];
 
/* check command line arguments */
if (argc != 3) {
printf("Usage: %s <configuration file> <output file>\n", argv[0]);
exit(1);
}
confName = argv[1];
outName = argv[2];
/* create partition table */
conf = fopen(confName, "rt");
if (conf == NULL) {
error("cannot open configuration file '%s'", confName);
}
lineNumber = 0;
/* handle partition table entries */
while (fgets(line, LINE_SIZE, conf) != NULL) {
lineNumber++;
p = line;
while (*p == ' ' || *p == '\t') {
p++;
}
if (*p == '\0' || *p == '\n' || *p == '#') {
continue;
}
if (!parseNumber(&p, &partNum)) {
error("cannot read partition number in config file '%s', line %d",
confName, lineNumber);
}
if (partNum >= 16) {
error("illegal partition number in config file '%s', line %d",
confName, lineNumber);
}
if (*p == '*') {
p++;
bootable = 0x80000000;
} else {
bootable = 0x00000000;
}
if (!parseNumber(&p, &partType)) {
error("cannot read partition type in config file '%s', line %d",
confName, lineNumber);
}
if ((partType & 0x80000000) != 0) {
error("illegal partition type in config file '%s', line %d",
confName, lineNumber);
}
if (!parseNumber(&p, &partStart)) {
error("cannot read start sector in config file '%s', line %d",
confName, lineNumber);
}
if (partStart < 32) {
error("illegal start sector in config file '%s', line %d",
confName, lineNumber);
}
if (!parseNumber(&p, &partLast)) {
error("cannot read last sector in config file '%s', line %d",
confName, lineNumber);
}
if (partLast < partStart) {
error("illegal last sector in config file '%s', line %d",
confName, lineNumber);
}
partSize = partLast - partStart + 1;
if (!parseString(&p, descr)) {
error("cannot read description in config file '%s', line %d",
confName, lineNumber);
}
if (strlen(descr) >= DESCR_SIZE) {
error("description too long in config file '%s', line %d",
confName, lineNumber);
}
if (partType != 0) {
ptr[partNum].type = bootable | partType;
ptr[partNum].start = partStart;
ptr[partNum].size = partSize;
memset(ptr[partNum].descr, 0, DESCR_SIZE);
strcpy(ptr[partNum].descr, descr);
} else {
ptr[partNum].type = 0;
ptr[partNum].start = 0;
ptr[partNum].size = 0;
memset(ptr[partNum].descr, 0, DESCR_SIZE);
}
}
fclose(conf);
/* next, show partition table */
printf("Partitions:\n");
printf(" # b type start last size description\n");
for (partNum = 0; partNum < NPE; partNum++) {
if (ptr[partNum].type != 0) {
partLast = ptr[partNum].start + ptr[partNum].size - 1;
} else {
partLast = 0;
}
printf("%2lu %s 0x%08lX 0x%08lX 0x%08lX 0x%08lX %s\n",
partNum,
ptr[partNum].type & 0x80000000 ? "*" : " ",
ptr[partNum].type & 0x7FFFFFFF,
ptr[partNum].start,
partLast,
ptr[partNum].size,
ptr[partNum].descr);
}
/* finally, write partition table to output file */
convertPartitionTable(ptr, NPE);
out = fopen(outName, "wb");
if (out == NULL) {
error("cannot open output file '%s'", outName);
}
if (fwrite(ptr, 1, SECTOR_SIZE, out) != SECTOR_SIZE) {
error("cannot write partition table to output file '%s'", outName);
}
fclose(out);
/* done */
return 0;
}
/mkptbl/Makefile
0,0 → 1,14
#
# Makefile for generating a partition table
#
 
all: parttbl
 
parttbl: mkptbl disk.part
./mkptbl disk.part parttbl
 
mkptbl: mkptbl.c
gcc -m32 -g -Wall -o mkptbl mkptbl.c
 
clean:
rm -f *~ mkptbl parttbl
/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_ */
/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_ */
/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_ */

powered by: WebSVN 2.1.0

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