/*
|
/*
|
* main.c -- program to write the partition table
|
* main.c -- program to write the partition table
|
* and the bootblock on a hard disk
|
* and the bootblock on a hard disk
|
*/
|
*/
|
|
|
|
|
#include "types.h"
|
#include "types.h"
|
#include "stdarg.h"
|
#include "stdarg.h"
|
#include "iolib.h"
|
#include "iolib.h"
|
#include "start.h"
|
#include "start.h"
|
#include "idedsk.h"
|
#include "idedsk.h"
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
void error(char *fmt, ...) {
|
void error(char *fmt, ...) {
|
va_list ap;
|
va_list ap;
|
|
|
va_start(ap, fmt);
|
va_start(ap, fmt);
|
printf("Error: ");
|
printf("Error: ");
|
vprintf(fmt, ap);
|
vprintf(fmt, ap);
|
printf(", halting...\n");
|
printf(", halting...\n");
|
va_end(ap);
|
va_end(ap);
|
while (1) ;
|
while (1) ;
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
/*
|
/*
|
* the boot block byte array need not be word-aligned
|
* the boot block byte array need not be word-aligned
|
*/
|
*/
|
unsigned char mboot[32 * SECTOR_SIZE] = {
|
unsigned char mboot[32 * SECTOR_SIZE] = {
|
#include "mboot.dump"
|
#include "mboot.dump"
|
};
|
};
|
|
|
|
|
/*
|
/*
|
* the write buffer must be word-aligned
|
* the write buffer must be word-aligned
|
*/
|
*/
|
unsigned int wrBuf[32 * SECTOR_SIZE / sizeof(unsigned int)];
|
unsigned int wrBuf[32 * SECTOR_SIZE / sizeof(unsigned int)];
|
|
|
|
|
/*
|
/*
|
* copy byte array to write buffer
|
* copy byte array to write buffer
|
*/
|
*/
|
void copyBootBlock(void) {
|
void copyBootBlock(void) {
|
unsigned char *p;
|
unsigned char *p;
|
unsigned char *q;
|
unsigned char *q;
|
int i;
|
int i;
|
|
|
p = (unsigned char *) wrBuf;
|
p = (unsigned char *) wrBuf;
|
q = (unsigned char *) mboot;
|
q = (unsigned char *) mboot;
|
for (i = 0; i < 32 * SECTOR_SIZE; i++) {
|
for (i = 0; i < 32 * SECTOR_SIZE; i++) {
|
*p++ = *q++;
|
*p++ = *q++;
|
}
|
}
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
static char *exceptionCause[32] = {
|
static char *exceptionCause[32] = {
|
/* 00 */ "terminal 0 transmitter interrupt",
|
/* 00 */ "terminal 0 transmitter interrupt",
|
/* 01 */ "terminal 0 receiver interrupt",
|
/* 01 */ "terminal 0 receiver interrupt",
|
/* 02 */ "terminal 1 transmitter interrupt",
|
/* 02 */ "terminal 1 transmitter interrupt",
|
/* 03 */ "terminal 1 receiver interrupt",
|
/* 03 */ "terminal 1 receiver interrupt",
|
/* 04 */ "keyboard interrupt",
|
/* 04 */ "keyboard interrupt",
|
/* 05 */ "unknown interrupt",
|
/* 05 */ "unknown interrupt",
|
/* 06 */ "unknown interrupt",
|
/* 06 */ "unknown interrupt",
|
/* 07 */ "unknown interrupt",
|
/* 07 */ "unknown interrupt",
|
/* 08 */ "disk interrupt",
|
/* 08 */ "disk interrupt",
|
/* 09 */ "unknown interrupt",
|
/* 09 */ "unknown interrupt",
|
/* 10 */ "unknown interrupt",
|
/* 10 */ "unknown interrupt",
|
/* 11 */ "unknown interrupt",
|
/* 11 */ "unknown interrupt",
|
/* 12 */ "unknown interrupt",
|
/* 12 */ "unknown interrupt",
|
/* 13 */ "unknown interrupt",
|
/* 13 */ "unknown interrupt",
|
/* 14 */ "timer interrupt",
|
/* 14 */ "timer 0 interrupt",
|
/* 15 */ "unknown interrupt",
|
/* 15 */ "timer 1 interrupt",
|
/* 16 */ "bus timeout exception",
|
/* 16 */ "bus timeout exception",
|
/* 17 */ "illegal instruction exception",
|
/* 17 */ "illegal instruction exception",
|
/* 18 */ "privileged instruction exception",
|
/* 18 */ "privileged instruction exception",
|
/* 19 */ "divide instruction exception",
|
/* 19 */ "divide instruction exception",
|
/* 20 */ "trap instruction exception",
|
/* 20 */ "trap instruction exception",
|
/* 21 */ "TLB miss exception",
|
/* 21 */ "TLB miss exception",
|
/* 22 */ "TLB write exception",
|
/* 22 */ "TLB write exception",
|
/* 23 */ "TLB invalid exception",
|
/* 23 */ "TLB invalid exception",
|
/* 24 */ "illegal address exception",
|
/* 24 */ "illegal address exception",
|
/* 25 */ "privileged address exception",
|
/* 25 */ "privileged address exception",
|
/* 26 */ "unknown exception",
|
/* 26 */ "unknown exception",
|
/* 27 */ "unknown exception",
|
/* 27 */ "unknown exception",
|
/* 28 */ "unknown exception",
|
/* 28 */ "unknown exception",
|
/* 29 */ "unknown exception",
|
/* 29 */ "unknown exception",
|
/* 30 */ "unknown exception",
|
/* 30 */ "unknown exception",
|
/* 31 */ "unknown exception"
|
/* 31 */ "unknown exception"
|
};
|
};
|
|
|
|
|
int defaultISR(int irq) {
|
int defaultISR(int irq) {
|
printf("\n%s\n", exceptionCause[irq]);
|
printf("\n%s\n", exceptionCause[irq]);
|
return 0; /* do not skip any instruction */
|
return 0; /* do not skip any instruction */
|
}
|
}
|
|
|
|
|
void initInterrupts(void) {
|
void initInterrupts(void) {
|
int i;
|
int i;
|
|
|
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
setISR(i, defaultISR);
|
setISR(i, defaultISR);
|
}
|
}
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
Bool checkDiskReady(void) {
|
Bool checkDiskReady(void) {
|
int tries;
|
int tries;
|
int i;
|
int i;
|
|
|
for (tries = 0; tries < 10; tries++) {
|
for (tries = 0; tries < 10; tries++) {
|
for (i = 0; i < 500000; i++) {
|
for (i = 0; i < 500000; i++) {
|
if ((*DISK_CTRL & DISK_CTRL_READY) != 0) {
|
if ((*DISK_CTRL & DISK_CTRL_READY) != 0) {
|
return TRUE;
|
return TRUE;
|
}
|
}
|
}
|
}
|
printf(".");
|
printf(".");
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
|
|
unsigned long getDiskSize(void) {
|
unsigned long getDiskSize(void) {
|
return *DISK_CAP;
|
return *DISK_CAP;
|
}
|
}
|
|
|
|
|
Bool readDisk(unsigned long sector,
|
Bool readDisk(unsigned long sector,
|
unsigned int count,
|
unsigned int count,
|
unsigned int *addr) {
|
unsigned int *addr) {
|
unsigned int n;
|
unsigned int n;
|
unsigned int *p;
|
unsigned int *p;
|
unsigned int i;
|
unsigned int i;
|
|
|
while (count != 0) {
|
while (count != 0) {
|
n = count > 8 ? 8 : count;
|
n = count > 8 ? 8 : count;
|
*DISK_SCT = sector;
|
*DISK_SCT = sector;
|
*DISK_CNT = n;
|
*DISK_CNT = n;
|
*DISK_CTRL = DISK_CTRL_STRT;
|
*DISK_CTRL = DISK_CTRL_STRT;
|
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
|
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
|
if (*DISK_CTRL & DISK_CTRL_ERR) {
|
if (*DISK_CTRL & DISK_CTRL_ERR) {
|
return FALSE;
|
return FALSE;
|
}
|
}
|
p = DISK_BUFFER;
|
p = DISK_BUFFER;
|
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
|
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
|
*addr++ = *p++;
|
*addr++ = *p++;
|
}
|
}
|
sector += n;
|
sector += n;
|
count -= n;
|
count -= n;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
|
|
Bool writeDisk(unsigned long sector,
|
Bool writeDisk(unsigned long sector,
|
unsigned int count,
|
unsigned int count,
|
unsigned int *addr) {
|
unsigned int *addr) {
|
unsigned int n;
|
unsigned int n;
|
unsigned int *p;
|
unsigned int *p;
|
unsigned int i;
|
unsigned int i;
|
|
|
while (count != 0) {
|
while (count != 0) {
|
n = count > 8 ? 8 : count;
|
n = count > 8 ? 8 : count;
|
p = DISK_BUFFER;
|
p = DISK_BUFFER;
|
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
|
for (i = 0; i < n * SECTOR_SIZE / sizeof(unsigned int); i++) {
|
*p++ = *addr++;
|
*p++ = *addr++;
|
}
|
}
|
*DISK_SCT = sector;
|
*DISK_SCT = sector;
|
*DISK_CNT = n;
|
*DISK_CNT = n;
|
*DISK_CTRL = DISK_CTRL_WRT | DISK_CTRL_STRT;
|
*DISK_CTRL = DISK_CTRL_WRT | DISK_CTRL_STRT;
|
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
|
while ((*DISK_CTRL & DISK_CTRL_DONE) == 0) ;
|
if (*DISK_CTRL & DISK_CTRL_ERR) {
|
if (*DISK_CTRL & DISK_CTRL_ERR) {
|
return FALSE;
|
return FALSE;
|
}
|
}
|
sector += n;
|
sector += n;
|
count -= n;
|
count -= n;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
|
|
/**************************************************************/
|
/**************************************************************/
|
|
|
|
|
void main(void) {
|
void main(void) {
|
unsigned long numSectors;
|
unsigned long numSectors;
|
|
|
/* init interrupts */
|
/* init interrupts */
|
initInterrupts();
|
initInterrupts();
|
/* check disk ready */
|
/* check disk ready */
|
if (!checkDiskReady()) {
|
if (!checkDiskReady()) {
|
error("disk not ready");
|
error("disk not ready");
|
}
|
}
|
/* determine disk size */
|
/* determine disk size */
|
numSectors = getDiskSize();
|
numSectors = getDiskSize();
|
printf("Disk has %lu (0x%lX) sectors.\n",
|
printf("Disk has %lu (0x%lX) sectors.\n",
|
numSectors, numSectors);
|
numSectors, numSectors);
|
if (numSectors < 32) {
|
if (numSectors < 32) {
|
error("disk is too small");
|
error("disk is too small");
|
}
|
}
|
/* copy boot block to write buffer */
|
/* copy boot block to write buffer */
|
copyBootBlock();
|
copyBootBlock();
|
/* write boot block to disk */
|
/* write boot block to disk */
|
printf("Writing boot block to disk...\n");
|
printf("Writing boot block to disk...\n");
|
if (!writeDisk(0, 32, wrBuf)) {
|
if (!writeDisk(0, 32, wrBuf)) {
|
error("cannot write boot block to disk");
|
error("cannot write boot block to disk");
|
}
|
}
|
/* done */
|
/* done */
|
printf("Halting...\n");
|
printf("Halting...\n");
|
}
|
}
|
|
|