first version with C page table handling that works

This commit is contained in:
Markus Fröschle
2014-09-28 11:27:07 +00:00
parent bb7ae911dc
commit 1345d7c808
7 changed files with 528 additions and 520 deletions

View File

@@ -45,22 +45,37 @@
.extern _irq5_handler
.extern _irq7_handler
/* Register read/write macros */
#define MCF_EPORT_EPPAR __MBAR+0xF00
#define MCF_EPORT_EPDDR __MBAR+0xF04
#define MCF_EPORT_EPIER __MBAR+0xF05
#define MCF_EPORT_EPDR __MBAR+0xF08
#define MCF_EPORT_EPPDR __MBAR+0xF09
#define MCF_EPORT_EPFR __MBAR+0xF0C
#define MCF_GPIO_PODR_FEC1L __MBAR+0xA07
#define MCF_PSC0_PSCTB_8BIT __MBAR+0x860C
.global _vec_init
// interrupt sources
/* Register read/write equates */
/* MMU */
.equ MCF_MMU_MMUCR, __MMUBAR
.equ MCF_MMU_MMUOR, __MMUBAR+0x04
.equ MCF_MMU_MMUSR, __MMUBAR+0x08
.equ MCF_MMU_MMUAR, __MMUBAR+0x10
.equ MCF_MMU_MMUTR, __MMUBAR+0x14
.equ MCF_MMU_MMUDR, __MMUBAR+0x18
/* EPORT flag register */
.equ MCF_EPORT_EPFR, __MBAR+0xf0c
/* FEC1 port output data direction register */
.equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07
/* PSC0 transmit buffer register */
.equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c
/* GPT mode select register */
.equ MCF_GPT0_GMS, __MBAR+0x800
/* Slice timer 0 count register */
.equ MCF_SLT0_SCNT, __MBAR+0x908
/* interrupt sources */
.equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1
.equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2
.equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3
@@ -115,82 +130,12 @@
// Atari register equates (provided by FPGA)
.equ vbasehi, 0xffff8201
//mmu ---------------------------------------------------
/* Register read/write macros */
#define MCF_MMU_MMUCR __MMUBAR
#define MCF_MMU_MMUOR __MMUBAR + 0x04
#define MCF_MMU_MMUSR __MMUBAR + 0x08
#define MCF_MMU_MMUAR __MMUBAR + 0x10
#define MCF_MMU_MMUTR __MMUBAR + 0x14
#define MCF_MMU_MMUDR __MMUBAR + 0x18
/* Bit definitions and macros for MCF_MMU_MMUCR */
#define MCF_MMU_MMUCR_EN (0x1)
#define MCF_MMU_MMUCR_ASM (0x2)
/* Bit definitions and macros for MCF_MMU_MMUOR */
#define MCF_MMU_MMUOR_UAA (0x1) /* update allocation address, i.e. write to TLB */
#define MCF_MMU_MMUOR_ACC (0x2) /* activate access to TLB */
#define MCF_MMU_MMUOR_RW (0x4) /* read/write TLB */
#define MCF_MMU_MMUOR_ADR (0x8) /* search by address/TLB address */
#define MCF_MMU_MMUOR_ITLB (0x10) /* act on instruction/data TLBs */
#define MCF_MMU_MMUOR_CAS (0x20) /* clear all unlocked TLBs with matching ASID */
#define MCF_MMU_MMUOR_CNL (0x40) /* clear all unlocked TLBs regardless of ASID */
#define MCF_MMU_MMUOR_CA (0x80) /* clear all TLBs */
#define MCF_MMU_MMUOR_STLB (0x100) /* search TLBs */
#define MCF_MMU_MMUOR_AA(x) (((x) & 0xFFFF) << 0x10) /* TLB allocation address */
/* Bit definitions and macros for MCF_MMU_MMUSR */
#define MCF_MMU_MMUSR_HIT (0x2) /* last lookup had a hit in TLB */
#define MCF_MMU_MMUSR_WF (0x8) /* indicate write fault */
#define MCF_MMU_MMUSR_RF (0x10) /* indicate read fault */
#define MCF_MMU_MMUSR_SPF (0x20) /* indicate supervisor protect fault */
/* Bit definitions and macros for MCF_MMU_MMUAR */
#define MCF_MMU_MMUAR_FA(x) (((x) & 0xFFFFFFFF) << 0)
/* Bit definitions and macros for MCF_MMU_MMUTR */
#define MCF_MMU_MMUTR_V (0x1) /* valid bit for TLB */
#define MCF_MMU_MMUTR_SG (0x2) /* set page as shared global */
#define MCF_MMU_MMUTR_ID(x) (((x) & 0xFF) << 0x2) /* ASID (address space id) of page */
#define MCF_MMU_MMUTR_VA(x) (((x) & 0x3FFFFF) << 0xA) /* virtual address of page */
/* Bit definitions and macros for MCF_MMU_MMUDR */
#define MCF_MMU_MMUDR_LK (0x2) /* lock page */
#define MCF_MMU_MMUDR_X (0x4) /* allow code execution in memory page */
#define MCF_MMU_MMUDR_W (0x8) /* allow write to memory page */
#define MCF_MMU_MMUDR_R (0x10) /* allow read from memory page */
#define MCF_MMU_MMUDR_SP (0x20) /* supervisor protect memory page */
#define MCF_MMU_MMUDR_CM(x) (((x) & 0x3) << 0x6) /* cache mode */
#define MCF_MMU_MMUDR_SZ(x) (((x) & 0x3) << 0x8) /* page size */
#define MCF_MMU_MMUDR_PA(x) (((x) & 0x3FFFFF) << 0xA) /* page physical address */
#define std_mmutr (MCF_MMU_MMUTR_SG | MCF_MMU_MMUTR_V)
#define writethrough_mmudr (MCF_MMU_MMUDR_SZ(00) | MCF_MMU_MMUDR_CM(00) | MCF_MMU_MMUDR_R | MCF_MMU_MMUDR_W | MCF_MMU_MMUDR_X)
#define copyback_mmudr (MCF_MMU_MMUDR_SZ(00) | MCF_MMU_MMUDR_CM(01) | MCF_MMU_MMUDR_R | MCF_MMU_MMUDR_W | MCF_MMU_MMUDR_X)
/*
*
* General Purpose Timers (GPT)
*
* macros
*/
/* Register read/write macros */
#define MCF_GPT0_GMS __MBAR+0x800
/*
*
* Slice Timers (SLT)
*
*/
#define MCF_SLT0_SCNT __MBAR+0x908
/**********************************************************/
// macros
/**********************************************************/
.altmacro
.macro irq vector,int_mask,clr_int
move.w #0x2700,sr // disable interrupt
@@ -207,25 +152,6 @@
rts
.endm
/*
* FIXME: this is a GNU gas kludge. Ugly, but I just can't come up with any smarter solution
*
* GNU as does not support multi-character constants. At least I don't know of any way it would.
* The following might look more than strange, but I considered the statement
*
* mchar move.l, 'T,'E,'S,'T,-(SP)
*
* somewhat more readable than
*
* move.l #1413829460,-(SP)
*
* If anybody knows of any better way on how to do this - please do!
*
*/
.macro mchar st,a,b,c,d,tgt
\st #\a << 24|\b<<16|\c<<8|\d,\tgt
.endm
.text
_vec_init:
move.l a2,-(sp) // Backup registers
@@ -323,16 +249,17 @@ std_exc_vec:
movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers
lsr.l #2,d0 // shift vector number in place
cmp.l #33,d0
beq noprint
cmp.l #34,d0
cmp.l #33,d0 // do not debug-print various traps
beq noprint // this would slow down interrupt
cmp.l #34,d0 // processing enormously
beq noprint
cmp.l #45,d0
beq noprint
cmp.l #46,d0
beq noprint
move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception
move.l d0,-(sp) // provide it to xprintf()
move.l d0,-(sp) // vector number
pea exception_text
jsr _xprintf // call xprintf()
add.l #3*4,sp // adjust stack
@@ -349,14 +276,15 @@ noprint:
move.l 4(sp),a5 // restore a5
move.l d0,4(sp) // store exception routine address
//move.w 10(sp),d0 // restore original SR
//bset #13,d0 // set supervisor bit
//move.w d0,sr //
// FIXME: what does this do and why?
move.w 10(sp),d0 // restore original SR
bset #13,d0 // set supervisor bit
move.w d0,sr //
move.l (sp)+,d0 // restore d0
rts // jump to exception routine
exception_text:
.ascii "DEBUG: EXCEPTION %d caught at %p"
.ascii "DEBUG: EXCEPTION 0x%x caught at %p"
.byte 13, 10, 0
.align 4
@@ -369,48 +297,27 @@ reset_vector:
access:
move.w #0x2700,sr // disable interrupts
move.l d0,-(sp) // ++ vr
move.w 4(sp),d0 // get format_status word from stack
andi.l #0x0c03,d0 // mask out fault status bits
cmpi.l #0x0401,d0 // TLB miss on opword of instruction fetch?
beq access_mmu // yes
cmpi.l #0x0402,d0 // TLB miss on extension word of instruction fetch?
beq access_mmu // yes
cmpi.l #0x0802,d0 // TLB miss on data write?
beq access_mmu // yes
cmpi.l #0x0c02,d0 // TLB miss on data read, or read-modify-write?
beq access_mmu // yes
link a6,#-4 * 4 // make room for gcc scratch registers
movem.l d0-d1/a0-a1,(sp) // and save them
bra bus_error // everything else is a classic bus error
move.l 4(a6),-(sp) // get format_status longword
move.l 8(a6),-(sp) // PC at exception
move.l MCF_MMU_MMUAR,-(sp) // fault address
move.l MCF_MMU_MMUSR,-(sp) // MMU status register
jsr _mmutr_miss
lea 4 * 4(sp),sp // adjust stack
access_mmu:
move.l MCF_MMU_MMUSR,d0 // did the last fault hit in TLB?
btst #1,d0 // yes, it did. So we already mapped that page
bne bus_error // and this must be a real bus error
move.l MCF_MMU_MMUAR,d0
cmp.l #__FASTRAM_END,d0 // above max User RAM area?
bge bus_error // -> bus error
lea -3 * 4(sp),sp // save gcc scratch registers
movem.l d1/a0-a1,(sp)
move.l 3 * 4 + 4 (sp),-(sp) // push exception stack frame
move.l 5 * 4 + 4 (sp),-(sp) // push program counter at exception
move.l d0,-(sp) // fault address
jsr _mmutr_miss // else we have an MMU TLB miss
add.l #3 * 4,sp // adjust stack
movem.l (sp),d1/a0-a1 // restore gcc scratch registers
lea 3 * 4(sp),sp
move.l (sp)+,d0 // restore register
tst.l d0 // exception handler signals bus error
bne bus_error
movem.l (sp),d0-d1/a0-a1 // restore stack
unlk a6
rte
bus_error:
move.l (sp)+,d0 // restore register
movem.l (sp),d0-d1/a0-a1
unlk a6
bra std_exc_vec
zero_divide:
@@ -587,10 +494,6 @@ acsi_dma: // atari dma
move.l d1,-(sp)
lea MCF_PSC0_PSCTB_8BIT,a1 // ++ vr
mchar move.l, 'D,'M','A,'\ ,(a1)
//move.l #"DMA ",(a1)
mchar move.l,'I,'N,'T,'!,(a1)
// move.l #'INT!',(a1)
lea 0xf0020110,a5 // fifo daten
acsi_dma_start:
@@ -673,7 +576,10 @@ irq7:
*
* GPT0 is used as input trigger. It is connected to the TIN0 signal of
* the FPGA and triggers everytime vbasehi is written to, i.e.
* when the video base address gets changed
* when the video base address gets changed. In the "MiNT-compatible MMU"-version this
* doesn't do anything, currently, but
* TODO: could be used for e.g. activating copyback cache mode on those ST-RAM pages
* that aren't video pages.
*/