This commit is contained in:
Markus Fröschle
2015-11-16 15:20:43 +00:00
parent ebdc333c6d
commit ba0f01d09c
5 changed files with 379 additions and 376 deletions

View File

@@ -178,7 +178,7 @@ ver:
touch include/version.h touch include/version.h
.PHONY: tos .PHONY: tos
tos: tos:
(cd tos; make) (cd tos; $(MAKE))
.PHONY: clean .PHONY: clean
clean: clean:

View File

@@ -30,7 +30,7 @@
#define SYSCLK 132000 /* NOTE: 132 _is_ correct. 133 _is_ wrong. Do not change! */ #define SYSCLK 132000 /* NOTE: 132 _is_ correct. 133 _is_ wrong. Do not change! */
#define BOOTFLASH_BASE_ADDRESS 0xE0000000 #define BOOTFLASH_BASE_ADDRESS 0xE0000000
#define BOOTFLASH_SIZE 0x800000 /* FireBee has 8 MByte Flash */ #define BOOTFLASH_SIZE 0x800000 /* FireBee has 8 MByte Flash */
#define BOOTFLASH_BAM (BOOTFLASH_SIZE - 1) #define BOOTFLASH_BAM (BOOTFLASH_SIZE - 1)
#define SDRAM_START 0x00000000 /* start at address 0 */ #define SDRAM_START 0x00000000 /* start at address 0 */

View File

@@ -375,10 +375,11 @@ void BaS(void)
mmu_init(); mmu_init();
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("copy EmuTOS: "); xprintf("initialize Coldfire DMA: ");
dma_init(); dma_init();
xprintf("finished\r\n");
xprintf("copy EmuTOS: ");
/* copy EMUTOS */ /* copy EMUTOS */
src = (uint8_t *) EMUTOS; src = (uint8_t *) EMUTOS;
dma_memcpy(dst, src, EMUTOS_SIZE); dma_memcpy(dst, src, EMUTOS_SIZE);

View File

@@ -27,108 +27,108 @@
#include "m5484l.h" #include "m5484l.h"
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
.extern __SUP_SP .extern __SUP_SP
.extern _rom_entry .extern _rom_entry
.extern __RAMBAR0 .extern __RAMBAR0
.extern _rt_mod .extern _rt_mod
.extern _rt_ssp .extern _rt_ssp
.extern _rt_usp .extern _rt_usp
.extern _rt_vbr .extern _rt_vbr
.extern _mmutr_miss .extern _mmutr_miss
.extern __MBAR .extern __MBAR
.extern __MMUBAR .extern __MMUBAR
.extern _video_tlb .extern _video_tlb
.extern _video_sbt .extern _video_sbt
.extern _flush_and_invalidate_caches .extern _flush_and_invalidate_caches
.extern _get_bas_drivers .extern _get_bas_drivers
/* PCI interrupt handlers */ /* PCI interrupt handlers */
.extern _irq5_handler .extern _irq5_handler
.extern _irq6_handler .extern _irq6_handler
.extern _irq7_handler .extern _irq7_handler
.global _vec_init .global _vec_init
.global _std_exc_vec /* needed by driver_vec.c */ .global _std_exc_vec /* needed by driver_vec.c */
/* Register read/write equates */ /* Register read/write equates */
/* MMU */ /* MMU */
.equ MCF_MMU_MMUCR, __MMUBAR .equ MCF_MMU_MMUCR, __MMUBAR
.equ MCF_MMU_MMUOR, __MMUBAR+0x04 .equ MCF_MMU_MMUOR, __MMUBAR+0x04
.equ MCF_MMU_MMUSR, __MMUBAR+0x08 .equ MCF_MMU_MMUSR, __MMUBAR+0x08
.equ MCF_MMU_MMUAR, __MMUBAR+0x10 .equ MCF_MMU_MMUAR, __MMUBAR+0x10
.equ MCF_MMU_MMUTR, __MMUBAR+0x14 .equ MCF_MMU_MMUTR, __MMUBAR+0x14
.equ MCF_MMU_MMUDR, __MMUBAR+0x18 .equ MCF_MMU_MMUDR, __MMUBAR+0x18
/* EPORT flag register */ /* EPORT flag register */
.equ MCF_EPORT_EPFR, __MBAR+0xf0c .equ MCF_EPORT_EPFR, __MBAR+0xf0c
/* FEC1 port output data direction register */ /* FEC1 port output data direction register */
.equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07 .equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07
/* PSC0 transmit buffer register */ /* PSC0 transmit buffer register */
.equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c .equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c
/* GPT mode select register */ /* GPT mode select register */
.equ MCF_GPT0_GMS, __MBAR+0x800 .equ MCF_GPT0_GMS, __MBAR+0x800
/* Slice timer 0 count register */ /* Slice timer 0 count register */
.equ MCF_SLT0_SCNT, __MBAR+0x908 .equ MCF_SLT0_SCNT, __MBAR+0x908
// interrupt sources // interrupt sources
.equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1 .equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1
.equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2 .equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2
.equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3 .equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3
.equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4 .equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4
.equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5 .equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5
.equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6 .equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6
.equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7 .equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7
.equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt .equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt
.equ INT_SOURCE_USB_EP1ISR,16 // USB endpoint 1 interrupt .equ INT_SOURCE_USB_EP1ISR,16 // USB endpoint 1 interrupt
.equ INT_SOURCE_USB_EP2ISR,17 // USB endpoint 2 interrupt .equ INT_SOURCE_USB_EP2ISR,17 // USB endpoint 2 interrupt
.equ INT_SOURCE_USB_EP3ISR,18 // USB endpoint 3 interrupt .equ INT_SOURCE_USB_EP3ISR,18 // USB endpoint 3 interrupt
.equ INT_SOURCE_USB_EP4ISR,19 // USB endpoint 4 interrupt .equ INT_SOURCE_USB_EP4ISR,19 // USB endpoint 4 interrupt
.equ INT_SOURCE_USB_EP5ISR,20 // USB endpoint 5 interrupt .equ INT_SOURCE_USB_EP5ISR,20 // USB endpoint 5 interrupt
.equ INT_SOURCE_USB_EP6ISR,21 // USB endpoint 6 interrupt .equ INT_SOURCE_USB_EP6ISR,21 // USB endpoint 6 interrupt
.equ INT_SOURCE_USB_USBISR,22 // USB general interrupt .equ INT_SOURCE_USB_USBISR,22 // USB general interrupt
.equ INT_SOURCE_USB_USBAISR,23 // USB core interrupt .equ INT_SOURCE_USB_USBAISR,23 // USB core interrupt
.equ INT_SOURCE_USB_ANY,24 // OR of all USB interrupts .equ INT_SOURCE_USB_ANY,24 // OR of all USB interrupts
.equ INT_SOURCE_USB_DSPI_OVF,25 // DSPI overflow or underflow .equ INT_SOURCE_USB_DSPI_OVF,25 // DSPI overflow or underflow
.equ INT_SOURCE_USB_DSPI_RFOF,26 // receive FIFO overflow interrupt .equ INT_SOURCE_USB_DSPI_RFOF,26 // receive FIFO overflow interrupt
.equ INT_SOURCE_USB_DSPI_RFDF,27 // receive FIFO drain interrupt .equ INT_SOURCE_USB_DSPI_RFDF,27 // receive FIFO drain interrupt
.equ INT_SOURCE_USB_DSPI_TFUF,28 // transmit FIFO underflow interrupt .equ INT_SOURCE_USB_DSPI_TFUF,28 // transmit FIFO underflow interrupt
.equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt .equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt
.equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt .equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt
.equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt .equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt
.equ INT_SOURCE_PSC3,32 // PSC3 interrupt .equ INT_SOURCE_PSC3,32 // PSC3 interrupt
.equ INT_SOURCE_PSC2,33 // PSC2 interrupt .equ INT_SOURCE_PSC2,33 // PSC2 interrupt
.equ INT_SOURCE_PSC1,34 // PSC1 interrupt .equ INT_SOURCE_PSC1,34 // PSC1 interrupt
.equ INT_SOURCE_PSC0,35 // PSC0 interrupt .equ INT_SOURCE_PSC0,35 // PSC0 interrupt
.equ INT_SOURCE_CTIMERS,36 // combined source for comm timers .equ INT_SOURCE_CTIMERS,36 // combined source for comm timers
.equ INT_SOURCE_SEC,37 // SEC interrupt .equ INT_SOURCE_SEC,37 // SEC interrupt
.equ INT_SOURCE_FEC1,38 // FEC1 interrupt .equ INT_SOURCE_FEC1,38 // FEC1 interrupt
.equ INT_SOURCE_FEC0,39 // FEC0 interrupt .equ INT_SOURCE_FEC0,39 // FEC0 interrupt
.equ INT_SOURCE_I2C,40 // I2C interrupt .equ INT_SOURCE_I2C,40 // I2C interrupt
.equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt .equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt
.equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt .equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt
.equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt .equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt
.equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt .equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt
.equ INT_SOURCE_DMA,48 // multichannel DMA interrupt .equ INT_SOURCE_DMA,48 // multichannel DMA interrupt
.equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt .equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt
.equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt .equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt
.equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt .equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt
.equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt .equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt
.equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt .equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt
.equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt .equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt
.equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt .equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt
.equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt .equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt
.equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt .equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt
.equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt .equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt
.equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt .equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt
.equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt .equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt
// Atari register equates (provided by FPGA) // Atari register equates (provided by FPGA)
.equ vbasehi, 0xffff8201 .equ vbasehi, 0xffff8201
/* /*
* macros * macros
@@ -139,119 +139,119 @@
* flag from the EDGE PORT flag register, set the status register to the appropriate interrupt * flag from the EDGE PORT flag register, set the status register to the appropriate interrupt
* mask an jump through the corresponging vector * mask an jump through the corresponging vector
*/ */
.macro irq vector,int_mask,clr_int .macro irq vector,int_mask,clr_int
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
subq.l #8,sp subq.l #8,sp
movem.l d0/a5,(sp) // save registers movem.l d0/a5,(sp) // save registers
lea MCF_EPORT_EPFR,a5 lea MCF_EPORT_EPFR,a5
move.b #\clr_int,(a5) // clear int pending move.b #\clr_int,(a5) // clear int pending
movem.l (sp),d0/a5 // restore registers movem.l (sp),d0/a5 // restore registers
addq.l #8,sp addq.l #8,sp
move.l \vector,-(sp) move.l \vector,-(sp)
move #0x2\int_mask\()00,sr move #0x2\int_mask\()00,sr
rts rts
.endm .endm
.text .text
_vec_init: _vec_init:
move.l a2,-(sp) // Backup registers move.l a2,-(sp) // Backup registers
mov3q.l #-1,_rt_mod // rt_mod auf super mov3q.l #-1,_rt_mod // rt_mod auf super
clr.l _rt_ssp clr.l _rt_ssp
clr.l _rt_usp clr.l _rt_usp
clr.l _rt_vbr clr.l _rt_vbr
move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 move.l #__RAMBAR0,d0 // exception vectors reside in rambar0
movec d0,VBR movec d0,VBR
move.l d0,a0 move.l d0,a0
move.l a0,a2 move.l a0,a2
/* /*
* first, set standard vector for all exceptions * first, set standard vector for all exceptions
*/ */
init_vec: init_vec:
move.l #256,d0 move.l #256,d0
lea std_exc_vec(pc),a1 // standard vector lea std_exc_vec(pc),a1 // standard vector
init_vec_loop: init_vec_loop:
move.l a1,(a2)+ // set standard vector for all exceptions move.l a1,(a2)+ // set standard vector for all exceptions
subq.l #1,d0 subq.l #1,d0
bne init_vec_loop bne init_vec_loop
// set individual interrupt handler assignments // set individual interrupt handler assignments
move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table
lea reset_vector(pc),a1 // set reset vector lea reset_vector(pc),a1 // set reset vector
move.l a1,0x04(a0) move.l a1,0x04(a0)
lea access(pc),a1 // set illegal access exception handler lea access(pc),a1 // set illegal access exception handler
move.l a1,0x08(a0) move.l a1,0x08(a0)
// install spurious interrupt handler // install spurious interrupt handler
lea _lowlevel_isr_handler,a1 lea _lowlevel_isr_handler,a1
move.l a1,0x60(a0) move.l a1,0x60(a0)
// trap #0 (without any parameters for now) is used to provide BaS' driver addresses to the OS // trap #0 (without any parameters for now) is used to provide BaS' driver addresses to the OS
lea _get_bas_drivers(pc),a1 lea _get_bas_drivers(pc),a1
move.l a1,0x80(a0) // trap #0 exception vector move.l a1,0x80(a0) // trap #0 exception vector
// MFP non-autovector interrupt handlers. Those are just rerouted to their autovector counterparts // MFP non-autovector interrupt handlers. Those are just rerouted to their autovector counterparts
lea irq1(pc),a1 lea irq1(pc),a1
move.l a1,0x104(a0) move.l a1,0x104(a0)
lea irq2(pc),a1 lea irq2(pc),a1
move.l a1,0x108(a0) move.l a1,0x108(a0)
lea irq3(pc),a1 lea irq3(pc),a1
move.l a1,0x10c(a0) move.l a1,0x10c(a0)
lea irq4(pc),a1 lea irq4(pc),a1
move.l a1,0x110(a0) move.l a1,0x110(a0)
lea irq5(pc),a1 lea irq5(pc),a1
move.l a1,0x114(a0) move.l a1,0x114(a0)
lea irq6(pc),a1 lea irq6(pc),a1
move.l a1,0x118(a0) move.l a1,0x118(a0)
lea irq7(pc),a1 lea irq7(pc),a1
move.l a1,0x11c(a0) move.l a1,0x11c(a0)
// install lowlevel_isr_handler for the three GPT timers // install lowlevel_isr_handler for the three GPT timers
lea _lowlevel_isr_handler(pc),a1 lea _lowlevel_isr_handler(pc),a1
move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0)
move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0)
move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0)
// install lowlevel_isr_handler for the PSC3 interrupt // install lowlevel_isr_handler for the PSC3 interrupt
move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0)
// install lowlevel_isr_handler for Coldfire DMA interrupts // install lowlevel_isr_handler for Coldfire DMA interrupts
move.l a1,(INT_SOURCE_DMA + 64) * 4(a0) move.l a1,(INT_SOURCE_DMA + 64) * 4(a0)
// install lowlevel_isr_handler for the XLBPCI interrupt // install lowlevel_isr_handler for the XLBPCI interrupt
move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0) move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0)
// install lowlevel_isr_handler for the FEC0 interrupt // install lowlevel_isr_handler for the FEC0 interrupt
move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0) move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0)
#ifndef MACHINE_FIREBEE #ifndef MACHINE_FIREBEE
// FEC1 not wired on the FireBee (used for FPGA as GPIO), but available on other machines // FEC1 not wired on the FireBee (used for FPGA as GPIO), but available on other machines
move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0) move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0)
#endif #endif
#ifdef MACHINE_FIREBEE #ifdef MACHINE_FIREBEE
// timer vectors (triggers when vbashi gets changed, used for video page copy) // timer vectors (triggers when vbashi gets changed, used for video page copy)
move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0)
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
move.l (sp)+,a2 // Restore registers move.l (sp)+,a2 // Restore registers
rts rts
/* /*
@@ -260,289 +260,291 @@ init_vec_loop:
vector_table_start: vector_table_start:
std_exc_vec: std_exc_vec:
_std_exc_vec: _std_exc_vec:
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
subq.l #8,sp subq.l #8,sp
movem.l d0/a5,(sp) // save registers movem.l d0/a5,(sp) // save registers
move.w 8(sp),d0 // fetch vector move.w 8(sp),d0 // fetch vector
and.l #0x3fc,d0 // mask out vector number and.l #0x3fc,d0 // mask out vector number
//#define DBG_EXC //#define DBG_EXC
#ifdef DBG_EXC #ifdef DBG_EXC
// printout vector number of exception // printout vector number of exception
lea -4 * 4(sp),sp // reserve stack space lea -4 * 4(sp),sp // reserve stack space
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
lsr.l #2,d0 // shift vector number in place lsr.l #2,d0 // shift vector number in place
cmp.l #33,d0 cmp.l #33,d0
beq noprint beq noprint
cmp.l #34,d0 cmp.l #34,d0
beq noprint beq noprint
cmp.l #45,d0 cmp.l #45,d0
beq noprint beq noprint
cmp.l #46,d0 cmp.l #46,d0
beq noprint beq noprint
move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception
move.l d0,-(sp) // provide it to xprintf() move.l d0,-(sp) // provide it to xprintf()
pea exception_text pea exception_text
jsr _xprintf // call xprintf() jsr _xprintf // call xprintf()
add.l #3*4,sp // adjust stack add.l #3*4,sp // adjust stack
noprint: noprint:
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
lea 4 * 4(sp),sp lea 4 * 4(sp),sp
#endif /* DBG_EXC */ #endif /* DBG_EXC */
add.l _rt_vbr,d0 // + VBR add.l _rt_vbr,d0 // + VBR
move.l d0,a5 move.l d0,a5
move.l (a5),d0 // fetch exception routine address move.l (a5),d0 // fetch exception routine address
move.l 4(sp),a5 // restore a5 move.l 4(sp),a5 // restore a5
move.l d0,4(sp) // store exception routine address move.l d0,4(sp) // store exception routine address
move.w 10(sp),d0 // restore original SR (irq mask) move.w 10(sp),d0 // restore original SR (irq mask)
bset #13,d0 // set supervisor bit bset #13,d0 // set supervisor bit
move.w d0,sr // move.w d0,sr //
move.l (sp)+,d0 // restore d0 move.l (sp)+,d0 // restore d0
rts // jump to exception handler rts // jump to exception handler
exception_text: exception_text:
.ascii "DEBUG: EXCEPTION %d caught at %p" .ascii "DEBUG: EXCEPTION %d caught at %p"
.byte 13, 10, 0 .byte 13, 10, 0
.align 4 .align 4
reset_vector: reset_vector:
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
move.l #0x31415926,d0 move.l #0x31415926,d0
cmp.l 0x426,d0 // _resvalid: reset vector valid? cmp.l 0x426,d0 // _resvalid: reset vector valid?
beq std_exc_vec // yes-> beq std_exc_vec // yes->
jmp _rom_entry // no, cold start machine jmp _rom_entry // no, cold start machine
access: access:
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
link a6,#-4 * 4 // make room for gcc scratch registers link a6,#-4 * 4 // make room for gcc scratch registers
movem.l d0-d1/a0-a1,(sp) // save them movem.l d0-d1/a0-a1,(sp) // save them
move.l 4(a6),-(sp) // push format_status move.l 4(a6),-(sp) // push format_status
move.l 8(a6),-(sp) // pc at exception move.l 8(a6),-(sp) // pc at exception
move.l MCF_MMU_MMUAR,-(sp) // MMU fault address move.l MCF_MMU_MMUAR,-(sp) // MMU fault address
move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter
move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe
jsr _mmutr_miss // call C routine jsr _mmutr_miss // call C routine
lea 4 * 4(sp),sp // adjust stack lea 4 * 4(sp),sp // adjust stack
tst.l d0 // exception handler signals bus error tst.l d0 // exception handler signals bus error
bne bus_error bne bus_error
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 unlk a6
rte rte
bus_error: bus_error:
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 unlk a6
bra std_exc_vec // FIXME: this seems to be bogous... bra std_exc_vec // FIXME: this seems to be bogous...
zero_divide: zero_divide:
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
move.l a0,-(sp) move.l a0,-(sp)
move.l d0,-(sp) move.l d0,-(sp)
move.l 12(sp),a0 // pc move.l 12(sp),a0 // pc
move.w (a0)+,d0 // command word move.w (a0)+,d0 // command word
btst #7,d0 // long? btst #7,d0 // long?
beq zd_word // no-> beq zd_word // no->
addq.l #2,a0 addq.l #2,a0
zd_word: zd_word:
and.l 0x3f,d0 // mask out ea field and.l 0x3f,d0 // mask out ea field
cmp.w #0x08,d0 // -(ax) or less? cmp.w #0x08,d0 // -(ax) or less?
ble zd_end ble zd_end
addq.l #2,a0 addq.l #2,a0
cmp.w #0x39,d0 // xxx.L cmp.w #0x39,d0 // xxx.L
bne zd_nal bne zd_nal
addq.l #2,a0 addq.l #2,a0
bra zd_end bra zd_end
zd_nal: cmp.w #0x3c,d0 // immediate? zd_nal: cmp.w #0x3c,d0 // immediate?
bne zd_end // no-> bne zd_end // no->
btst #7,d0 // long? btst #7,d0 // long?
beq zd_end // no beq zd_end // no
addq.l #2,a0 addq.l #2,a0
zd_end: zd_end:
move.l a0,12(sp) move.l a0,12(sp)
move.l (sp)+,d0 move.l (sp)+,d0
move.l (sp)+,a0 move.l (sp)+,a0
rte rte
#ifdef _NOT_USED_ #ifdef _NOT_USED_
linea: linea:
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
halt halt
nop nop
nop nop
linef: linef:
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
halt halt
nop nop
nop nop
format: format:
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
halt halt
nop nop
nop nop
//floating point //floating point
flpoow: flpoow:
move.w #0x2700,sr // disable interrupt move.w #0x2700,sr // disable interrupt
halt halt
nop nop
nop nop
#endif /* _NOT_USED */ #endif /* _NOT_USED */
irq1: irq 0x64, 1, 0x02 // Level 1 autovector interrupt (unused) irq1: irq 0x64, 1, 0x02 // Level 1 autovector interrupt (unused)
irq2: irq 0x68, 2, 0x04 // Level 2 autovector interrupt (horizontal blank) irq2: irq 0x68, 2, 0x04 // Level 2 autovector interrupt (horizontal blank)
irq3: irq 0x6c, 3, 0x08 // Level 3 autovector interrupt (unused) irq3: irq 0x6c, 3, 0x08 // Level 3 autovector interrupt (unused)
irq4: irq 0x70, 4, 0x10 // Level 4 autovector interrupt (vertical blank) irq4: irq 0x70, 4, 0x10 // Level 4 autovector interrupt (vertical blank)
#if defined(MACHINE_FIREBEE) /* these handlers are only meaningful for the Firebee */ #if defined(MACHINE_FIREBEE) /* these handlers are only meaningful for the Firebee */
irq5: //move.w #0x2700,sr // disable interrupts irq5: //move.w #0x2700,sr // disable interrupts
subq.l #4,sp // extra space subq.l #4,sp // extra space
link a6,#-4 * 4 // save gcc scratch registers link a6,#-4 * 4 // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
jsr _irq5_handler // call C handler routine jsr _irq5_handler // call C handler routine
tst.b d0 // handled? tst.b d0 // handled?
beq irq5_forward beq irq5_forward
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 unlk a6
addq.l #4,sp addq.l #4,sp
rte // return from exception rte // return from exception
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector
add.l _rt_vbr,a0 // add runtime vbr add.l _rt_vbr,a0 // add runtime vbr
move.l a0,4(a6) // put on stack move.l a0,4(a6) // put on stack
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 // unlk a6 //
move.w #0x2500,sr // set interrupt level move.w #0x2500,sr // set interrupt level
rts // jump through vector rts // jump through vector
/* /*
* irq6 needs special treatment since - because the Coldfire only supports autovector interrupts * irq6 needs special treatment since - because the Coldfire only supports autovector interrupts
* - the exception vector is provided by the simulated MFP from the FPGA * - the exception vector is provided by the simulated MFP from the FPGA
*/ */
irq6: move.w #0x2700,sr // disable interrupt irq6: move.w #0x2700,sr // disable interrupt
subq.l #4,sp // extra space subq.l #4,sp // extra space
link a6,#-4 * 4 // save gcc scratch registers link a6,#-4 * 4 // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
move.l 8(a6),-(sp) // format status word move.l 8(a6),-(sp) // format status word
move.l 12(a6),-(sp) // pc at exception move.l 12(a6),-(sp) // pc at exception
jsr _irq6_handler // call C handler jsr _irq6_handler // call C handler
lea 8(sp),sp // fix stack lea 8(sp),sp // fix stack
tst.b d0 // interrupt handled? tst.b d0 // interrupt handled?
beq irq6_forward // no, forward to TOS beq irq6_forward // no, forward to TOS
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 unlk a6
addq.l #4,sp // "extra space" not needed in this case addq.l #4,sp // "extra space" not needed in this case
rte rte
irq6_forward: irq6_forward:
move.l 0xf0020000,a0 // fetch "MFP interrupt vector" from FPGA move.l 0xf0020000,a0 // fetch "MFP interrupt vector" from FPGA
add.l _rt_vbr,a0 // add runtime VBR add.l _rt_vbr,a0 // add runtime VBR
move.l (a0),4(a6) // fetch handler address and put it on "extra space" move.l (a0),4(a6) // fetch handler address and put it on "extra space"
movem.l (sp),d0-d1/a0-a1 movem.l (sp),d0-d1/a0-a1
unlk a6 unlk a6
move.w #0x2600,sr // set interrupt mask to MFP level move.w #0x2600,sr // set interrupt mask to MFP level
rts // jump through vector rts // jump through vector
/* /*
* irq 7 = pseudo bus error * irq 7 = pseudo bus error
*/ */
irq7: irq7:
lea -12(sp),sp lea -12(sp),sp
movem.l d0/a0,(sp) movem.l d0/a0,(sp)
move.l __RAMBAR0+0x008,a0 // real access error handler move.l __RAMBAR0+0x008,a0 // real access error handler
move.l a0,8(sp) // this will be the return address for rts move.l a0,8(sp) // this will be the return address for rts
move.w 12(sp),d0 // format/vector word move.w 12(sp),d0 // format/vector word
andi.l #0xf000,d0 // keep only the format andi.l #0xf000,d0 // keep only the format
ori.l #2*4,d0 // simulate vector #2, no fault ori.l #2*4,d0 // simulate vector #2, no fault
move.w d0,12(sp) move.w d0,12(sp)
// TODO: Inside an interrupt handler, 16(sp) is the return address. // TODO: Inside an interrupt handler, 16(sp) is the return address.
// For an Access Error, it should be the address of the fault instruction instead // For an Access Error, it should be the address of the fault instruction instead
lea MCF_EPORT_EPFR,a0 lea MCF_EPORT_EPFR,a0
bset #7,(a0) // clear int 7 bset #7,(a0) // clear int 7
move.l (sp)+,d0 // restore registers move.l (sp)+,d0 // restore registers
move.l (sp)+,a0 move.l (sp)+,a0
rts // Forward to the Access Error handler rts // Forward to the Access Error handler
#else // handlers for M5484LITE #else // handlers for M5484LITE
irq5: move.w #0x2700,sr // disable interrupts irq5:
subq.l #4,sp // extra space move.w #0x2700,sr // disable interrupts
subq.l #4,sp // extra space
link a6,#-4 * 4 // save gcc scratch registers link a6,#-4 * 4 // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
jsr _irq5_handler // call C handler routine jsr _irq5_handler // call C handler routine
tst.b d0 // handled? tst.b d0 // handled?
beq irq5_forward beq irq5_forward
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 unlk a6
addq.l #4,sp addq.l #4,sp
rte // return from exception rte // return from exception
irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector irq5_forward:
add.l _rt_vbr,a0 // add runtime vbr move.l 0x74,a0 // fetch OS irq5 vector
move.l a0,4(a6) // put on stack add.l _rt_vbr,a0 // add runtime vbr
move.l a0,4(a6) // put on stack
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 // unlk a6 //
move.w #0x2500,sr // set interrupt level move.w #0x2500,sr // set interrupt level
rts // jump through vector rts // jump through vector
irq6: irq6:
irq 0x74,5,0x20 irq 0x74,5,0x20
irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE
move.w #0x2700,sr // disable interrupts move.w #0x2700,sr // disable interrupts
lea -4*4(sp),sp // save gcc scratch registers lea -4*4(sp),sp // save gcc scratch registers
movem.l d0-d1/a0-a1,(sp) movem.l d0-d1/a0-a1,(sp)
jsr _irq7_handler // call C handler routine jsr _irq7_handler // call C handler routine
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
lea 4 * 4(sp),sp lea 4 * 4(sp),sp
rte // return from exception rte // return from exception
irq7text: irq7text:
.data .data
.ascii "IRQ7!" .ascii "IRQ7!"
.dc.b 13,10,0 .dc.b 13,10,0
.text .text
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
/* /*
@@ -550,8 +552,8 @@ irq7text:
* isr_register_handler(int vector). If the higlevel routine (isr_execute_handler()) * isr_register_handler(int vector). If the higlevel routine (isr_execute_handler())
* returns != true, the call is forwarded to the OS (through its own vector base). * returns != true, the call is forwarded to the OS (through its own vector base).
*/ */
.global _lowlevel_isr_handler .global _lowlevel_isr_handler
.extern _isr_execute_handler .extern _isr_execute_handler
/* /*
@@ -567,33 +569,33 @@ irq7text:
* (sp) -> gcc scratch registers save area * (sp) -> gcc scratch registers save area
*/ */
_lowlevel_isr_handler: _lowlevel_isr_handler:
subq.l #4,sp // extra space subq.l #4,sp // extra space
link a6,#-4 * 4 // make room for link a6,#-4 * 4 // make room for
movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them, movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them,
// other registers will be taken care of by gcc itself // other registers will be taken care of by gcc itself
move.w 8(a6),d0 // fetch vector number from stack move.w 8(a6),d0 // fetch vector number from stack
lsr.l #2,d0 // move it in place lsr.l #2,d0 // move it in place
andi.l #0xff,d0 // mask it out andi.l #0xff,d0 // mask it out
move.l d0,-(sp) // push it move.l d0,-(sp) // push it
jsr _isr_execute_handler // call the C handler jsr _isr_execute_handler // call the C handler
addq.l #4,sp // adjust stack addq.l #4,sp // adjust stack
tst.b d0 // handled? tst.b d0 // handled?
beq lowlevel_forward // no, forward it to TOS beq lowlevel_forward // no, forward it to TOS
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 unlk a6
addq.l #4,sp // eliminate extra space addq.l #4,sp // eliminate extra space
rte rte
lowlevel_forward: lowlevel_forward:
move.l 8(a6),d0 // fetch OS irq vector move.l 8(a6),d0 // fetch OS irq vector
lsr.l #2,d0 // move it in place lsr.l #2,d0 // move it in place
andi.l #0xff,d0 // mask out vector number andi.l #0xff,d0 // mask out vector number
add.l _rt_vbr,d0 // add runtime vbr add.l _rt_vbr,d0 // add runtime vbr
move.l d0,4(a6) // put on stack as return address move.l d0,4(a6) // put on stack as return address
movem.l (sp),d0-d1/a0-a1 // restore registers movem.l (sp),d0-d1/a0-a1 // restore registers
unlk a6 // unlk a6 //
rts // jump through vector rts // jump through vector

View File

@@ -5,11 +5,11 @@
tos: jtagwait bascook vmem_test tos: jtagwait bascook vmem_test
jtagwait: jtagwait:
make -C $@ $(MAKE) -C $@
bascook: bascook:
make -C $@ $(MAKE) -C $@
vmem_test: vmem_test:
make -C $@ $(MAKE) -C $@