/*
    tt.S, Copyright  (c) by Silvio Dragone & David Reist,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.

    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.

    For further information, please visit http://www.tik.ee.ethz.ch/~topsy

    This software is provided under the terms of the GNU General Public Licence.

    A full copy of the GNU GPL is provided in the file COPYING found in the 
    development root of Topsy.
*/

#include "asm.h"
#include "cpu.h"

.text
		
	ENTRY(setTTBase)
	/* set TT L1 base address in CP15 register 2, bit <31:14> 
	 * arg 0 in a0:	address				          
	 */
	mov	ip, #0
	mcr	p15, 0, ip, c7, c7, 0		// flush I & D caches
//	mcr	p15, 0, ip, c9, c0, 0		// flush RB
	mcr	p15, 0, ip, c7, c10, 4	// drain WB
	mcr	p15, 0, r0, c2, c0, 0		// load page table pointer
	mcr	p15, 0, ip, c8, c7, 0		// flush I & D TLBs
	nop
	END(setTTBase)

	
	ENTRY(setDAC)
	/* set DAC (Domain Access Control) in CP15 register 3 
	 * arg 0 in a0:	DAC register value                    
	 */
	
	mcr	p15, 0, a0, c3, c0, 0		/* write to CP15 reg 3 (Domain Access Control) */
	nop
	END(setDAC)

	
	ENTRY(setTTL1Entry)
	/* set specified TT L1 entry            
	 * arg 0 in a0:	TT L1 base address      
	 * arg 1 in a1:	TT L1 index (0, 1, ...) 
	 * arg 2 in a2:	value                   
	 */

 	str	a2, [a0, a1, lsl #0x02]		/* write entry to memory */
	mcr	p15, 0, ip, c7, c10, 4		// drain WB
	END(setTTL1Entry)
	

	ENTRY(getTTL1Entry)
	/* get specified TT L1 entry
   * arg 0 in a0: TT L1 base address
   * arg 1 in a1: TT L1 index (0, 1, ...)
   * arg 2 in a2: pointer to value to be written
   */

	ldr ip, [a0, a1, lsl #0x02]   /* write entry to memory */
	str ip, [a2, #0]
	END(getTTL1Entry)


	ENTRY(setTTL2Entry)
	/* set specified TT L2 entry            
	 * arg 0 in a0:	TT L2 base address      
	 * arg 1 in a1:	TT L2 index (0, 1, ...) 
	 * arg 2 in a2:	value
	 */
	
 	str	a2, [a0, a1, lsl #0x02]		/* write entry to memory */
	END(setTTL2Entry)
	

	ENTRY(getTTL2Entry)
	/* set specified TT L2 entry            
	 * arg 0 in a0:	TT L2 base address      
	 * arg 1 in a1:	TT L2 index (0, 1, ...) 
	 * arg 2 in a2:	pointer to value to be written
	 */
	
	ldr ip, [a0, a1, lsl #0x02]
	str ip, [a2, #0]
	END(getTTL2Entry)

	
	ENTRY(enableMMU)
	/* enable MMU in CP15 register 1, bit 0 */
	mrc	p15, 0, ip, c1, c0, 0
	orr	ip, ip, #0x81		        /* ......b......m */
	mcr	p15, 0, ip, c1, c0, 0		/* write to CP15 reg 1 (control) */
	nop				        /* fetch for 3 cycles non-translated */
	nop
	nop					/* fetch now translated */
	END(enableMMU)


	ENTRY(flushTLBAll)
	/* invalidate entire data and instruction TLB */
	mov ip, #0
	mcr p15, 0, ip, c8, c7, 0
	nop
	END(flushTLBAll)

	
	ENTRY(flushTLBSingleD)
	/* invalidate virtual address in data TLB */
	/* virtual address is specified in a0     */
	mcr p15, 0, a0, c8, c6, 1
	nop
	END(flushTLBSingleD)


	ENTRY(flushTLBSingleI)
	/* invalidate virtual address in instruction TLB */
	/* virtual address is specified in a0            */
	mcr p15, 0, a0, c8, c5, 1
	nop
	END(flushTLBSingleI)


	ENTRY(flushTLBSingleU)
	/* invalidate virtual address in unified TLB */
	/* virtual address is specified in a0        */
	mcr p15, 0, a0, c8, c7, 1
	nop
	END(flushTLBSingleU)

