/* | |
* File: mcf5xxx.c | |
* Purpose: Generic high-level routines for generic ColdFire processors | |
* | |
* Notes: | |
* | |
* License: All software covered by license agreement in - | |
* docs/Freescale_Software_License.pdf | |
*/ | |
#include "common.h" | |
/********************************************************************/ | |
#define EXCEPTFMT "%s -- PC = %#08X\n" | |
/********************************************************************/ | |
/* | |
* This is the exception handler for all defined exceptions. Most | |
* exceptions do nothing, but some of the more important ones are | |
* handled to some extent. | |
* | |
* Called by asm_exception_handler | |
*/ | |
void | |
mcf5xxx_exception_handler (void *framep) | |
{ | |
switch (MCF5XXX_RD_SF_FORMAT(framep)) | |
{ | |
case 4: | |
case 5: | |
case 6: | |
case 7: | |
break; | |
default: | |
printf(EXCEPTFMT,"Illegal stack type", MCF5XXX_SF_PC(framep)); | |
break; | |
} | |
switch (MCF5XXX_RD_SF_VECTOR(framep)) | |
{ | |
case 2: | |
printf(EXCEPTFMT, "Access Error", MCF5XXX_SF_PC(framep)); | |
switch (MCF5XXX_RD_SF_FS(framep)) | |
{ | |
case 4: | |
printf("Error on instruction fetch\n"); | |
break; | |
case 8: | |
printf("Error on operand write\n"); | |
break; | |
case 9: | |
printf("Attempted write to write-protected space\n"); | |
break; | |
case 12: | |
printf("Error on operand read\n"); | |
break; | |
default: | |
printf("Reserved Fault Status Encoding\n"); | |
break; | |
} | |
break; | |
case 3: | |
printf(EXCEPTFMT, "Address Error", MCF5XXX_SF_PC(framep)); | |
switch (MCF5XXX_RD_SF_FS(framep)) | |
{ | |
case 4: | |
printf("Error on instruction fetch\n"); | |
break; | |
case 8: | |
printf("Error on operand write\n"); | |
break; | |
case 9: | |
printf("Attempted write to write-protected space\n"); | |
break; | |
case 12: | |
printf("Error on operand read\n"); | |
break; | |
default: | |
printf("Reserved Fault Status Encoding\n"); | |
break; | |
} | |
break; | |
case 4: | |
printf(EXCEPTFMT, "Illegal instruction", MCF5XXX_SF_PC(framep)); | |
break; | |
case 8: | |
printf(EXCEPTFMT, "Privilege violation", MCF5XXX_SF_PC(framep)); | |
break; | |
case 9: | |
printf(EXCEPTFMT, "Trace Exception", MCF5XXX_SF_PC(framep)); | |
break; | |
case 10: | |
printf(EXCEPTFMT, "Unimplemented A-Line Instruction", \ | |
MCF5XXX_SF_PC(framep)); | |
break; | |
case 11: | |
printf(EXCEPTFMT, "Unimplemented F-Line Instruction", \ | |
MCF5XXX_SF_PC(framep)); | |
break; | |
case 12: | |
printf(EXCEPTFMT, "Debug Interrupt", MCF5XXX_SF_PC(framep)); | |
break; | |
case 14: | |
printf(EXCEPTFMT, "Format Error", MCF5XXX_SF_PC(framep)); | |
break; | |
case 15: | |
printf(EXCEPTFMT, "Unitialized Interrupt", MCF5XXX_SF_PC(framep)); | |
break; | |
case 24: | |
printf(EXCEPTFMT, "Spurious Interrupt", MCF5XXX_SF_PC(framep)); | |
break; | |
case 25: | |
case 26: | |
case 27: | |
case 28: | |
case 29: | |
case 30: | |
case 31: | |
printf("Autovector interrupt level %d\n", | |
MCF5XXX_RD_SF_VECTOR(framep) - 24); | |
break; | |
case 32: | |
case 33: | |
case 34: | |
case 35: | |
case 36: | |
case 37: | |
case 38: | |
case 39: | |
case 40: | |
case 41: | |
case 42: | |
case 43: | |
case 44: | |
case 45: | |
case 46: | |
case 47: | |
printf("TRAP #%d\n", MCF5XXX_RD_SF_VECTOR(framep) - 32); | |
break; | |
case 5: | |
case 6: | |
case 7: | |
case 13: | |
case 16: | |
case 17: | |
case 18: | |
case 19: | |
case 20: | |
case 21: | |
case 22: | |
case 23: | |
case 48: | |
case 49: | |
case 50: | |
case 51: | |
case 52: | |
case 53: | |
case 54: | |
case 55: | |
case 56: | |
case 57: | |
case 58: | |
case 59: | |
case 60: | |
case 61: | |
case 62: | |
case 63: | |
printf("Reserved: #%d\n", MCF5XXX_RD_SF_VECTOR(framep)); | |
break; | |
default: | |
cpu_handle_interrupt(MCF5XXX_RD_SF_VECTOR(framep)); | |
break; | |
} | |
} | |
/********************************************************************/ | |
/* | |
* Interpret the reset values of D0 and D1 | |
* | |
* Parameters: | |
* d0 - the reset value of data register zero | |
* d1 - the reset value of data register one | |
*/ | |
void | |
mcf5xxx_interpret_d0d1(int d0, int d1) | |
{ | |
#ifdef DEBUG_PRINT | |
printf("\nColdFire Core Configuration:\n"); | |
printf("----------------------------\n"); | |
printf("Processor Family %#02x\n",MCF5XXX_D0_PF(d0)); | |
printf("ColdFire Core Version: %d\n",MCF5XXX_D0_VER(d0)); | |
printf("Processor Revision: %d\n",MCF5XXX_D0_REV(d1)); | |
printf("Bus Width: "); | |
switch (MCF5XXX_D1_BUSW(d1)) | |
{ | |
case 0: | |
printf("32-bit\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("ISA Version: "); | |
switch (MCF5XXX_D0_ISA(d0)) | |
{ | |
case 0: | |
printf("A\n"); | |
break; | |
case 1: | |
printf("B\n"); | |
break; | |
case 2: | |
printf("C\n"); | |
break; | |
case 8: | |
printf("A+\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("Debug Version: "); | |
switch (MCF5XXX_D0_DEBUG(d0)) | |
{ | |
case 0: | |
printf("A\n"); | |
break; | |
case 1: | |
printf("B\n"); | |
break; | |
case 2: | |
printf("C\n"); | |
break; | |
case 3: | |
printf("D\n"); | |
break; | |
case 4: | |
printf("E\n"); | |
break; | |
case 9: | |
printf("B+\n"); | |
break; | |
default : | |
printf("Reserved\n"); | |
} | |
printf("MAC: %s\n", MCF5XXX_D0_MAC(d0) ? "Yes" : "No"); | |
printf("DIV: %s\n", MCF5XXX_D0_DIV(d0) ? "Yes" : "No"); | |
printf("EMAC: %s\n", MCF5XXX_D0_EMAC(d0) ? "Yes" : "No"); | |
printf("FPU: %s\n", MCF5XXX_D0_FPU(d0) ? "Yes" : "No"); | |
printf("MMU: %s\n", MCF5XXX_D0_MMU(d0) ? "Yes" : "No"); | |
printf("RAM Bank 0 Size: "); | |
switch (MCF5XXX_D1_RAM0SIZ(d1)) | |
{ | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
printf("None\n"); | |
break; | |
case 4: | |
printf("4KB\n"); | |
break; | |
case 5: | |
printf("8KB\n"); | |
break; | |
case 6: | |
printf("16KB\n"); | |
break; | |
case 7: | |
printf("32KB\n"); | |
break; | |
case 8: | |
printf("64KB\n"); | |
break; | |
case 9: | |
printf("128KB\n"); | |
break; | |
case 10: | |
printf("256KB\n"); | |
break; | |
case 11: | |
printf("512KB\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("RAM Bank 1 Size: "); | |
switch (MCF5XXX_D1_RAM1SIZ(d1)) | |
{ | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
printf("None\n"); | |
break; | |
case 4: | |
printf("4KB\n"); | |
break; | |
case 5: | |
printf("8KB\n"); | |
break; | |
case 6: | |
printf("16KB\n"); | |
break; | |
case 7: | |
printf("32KB\n"); | |
break; | |
case 8: | |
printf("64KB\n"); | |
break; | |
case 9: | |
printf("128KB\n"); | |
break; | |
case 10: | |
printf("256KB\n"); | |
break; | |
case 11: | |
printf("512KB\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("ROM Bank 0 Size: "); | |
switch (MCF5XXX_D1_ROM0SIZ(d1)) | |
{ | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
printf("None\n"); | |
break; | |
case 4: | |
printf("4KB\n"); | |
break; | |
case 5: | |
printf("8KB\n"); | |
break; | |
case 6: | |
printf("16KB\n"); | |
break; | |
case 7: | |
printf("32KB\n"); | |
break; | |
case 8: | |
printf("64KB\n"); | |
break; | |
case 9: | |
printf("128KB\n"); | |
default: | |
printf("Reserved\n"); | |
} | |
printf("ROM Bank 1 Size: "); | |
switch (MCF5XXX_D1_ROM1SIZ(d1)) | |
{ | |
case 0: | |
case 1: | |
case 2: | |
case 3: | |
printf("None\n"); | |
break; | |
case 4: | |
printf("4KB\n"); | |
break; | |
case 5: | |
printf("8KB\n"); | |
break; | |
case 6: | |
printf("16KB\n"); | |
break; | |
case 7: | |
printf("32KB\n"); | |
break; | |
case 8: | |
printf("64KB\n"); | |
break; | |
case 9: | |
printf("128KB\n"); | |
default: | |
printf("Reserved\n"); | |
} | |
printf("Cache Line Size: "); | |
switch (MCF5XXX_D1_CL(d1)) | |
{ | |
case 0: | |
printf("16-byte\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("I-Cache Associativity: "); | |
switch (MCF5XXX_D1_ICA(d1)) | |
{ | |
case 0: | |
printf("Four-way\n"); | |
break; | |
case 1: | |
printf("Direct mapped\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("D-Cache Associativity: "); | |
switch (MCF5XXX_D1_DCA(d1)) | |
{ | |
case 0: | |
printf("Four-way\n"); | |
break; | |
case 1: | |
printf("Direct mapped\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("I-Cache Size: "); | |
switch (MCF5XXX_D1_ICSIZ(d1)) | |
{ | |
case 0: | |
printf("None\n"); | |
break; | |
case 1: | |
printf("512B\n"); | |
break; | |
case 2: | |
printf("1KB\n"); | |
break; | |
case 3: | |
printf("2KB\n"); | |
break; | |
case 4: | |
printf("4KB\n"); | |
break; | |
case 5: | |
printf("8KB\n"); | |
break; | |
case 6: | |
printf("16KB\n"); | |
break; | |
case 7: | |
printf("32KB\n"); | |
break; | |
case 8: | |
printf("64KB\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("D-Cache Size: "); | |
switch (MCF5XXX_D1_DCSIZ(d1)) | |
{ | |
case 0: | |
printf("None\n"); | |
break; | |
case 1: | |
printf("512B\n"); | |
break; | |
case 2: | |
printf("1KB\n"); | |
break; | |
case 3: | |
printf("2KB\n"); | |
break; | |
case 4: | |
printf("4KB\n"); | |
break; | |
case 5: | |
printf("8KB\n"); | |
break; | |
case 6: | |
printf("16KB\n"); | |
break; | |
case 7: | |
printf("32KB\n"); | |
break; | |
case 8: | |
printf("64KB\n"); | |
break; | |
default: | |
printf("Reserved\n"); | |
} | |
printf("\n"); | |
#else | |
/* Remove compiler warnings. */ | |
( void ) d0; | |
( void ) d1; | |
#endif | |
} | |
/********************************************************************/ | |
void | |
mcf5xxx_irq_enable (void) | |
{ | |
asm_set_ipl(0); | |
} | |
/********************************************************************/ | |
void | |
mcf5xxx_irq_disable (void) | |
{ | |
asm_set_ipl(7); | |
} | |
/********************************************************************/ | |
/* | |
* Write new interrupt vector handler into the vector table | |
* Return previous handler address | |
*/ | |
ADDRESS | |
mcf5xxx_set_handler (int vector, ADDRESS new_handler) | |
{ | |
ADDRESS old_handler; | |
extern uint32 __VECTOR_RAM[]; | |
old_handler = (ADDRESS) __VECTOR_RAM[vector]; | |
__VECTOR_RAM[vector] = (uint32)new_handler; | |
return old_handler; | |
} | |
/********************************************************************/ |