URL
https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk
Subversion Repositories openrisc_2011-10-31
[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [or1200/] [sim/] [or1200-ticksyscall.S] - Rev 477
Compare with Previous | Blame | View Log
#include "spr-defs.h"#include "board.h"/*Tick timer and system call simultaneous interrupt testWithin the test we'll use following global variables:r15 syscall interrupt counterr16 syscall function counterr17 timer interrupt counterThe test do the following:Setup tick interrupts to occur regularly, and then do a bunch of l.syssystems calls, checking that they all occur OKNote: if this test appears to continue without counting, it's mostlikely due to a tick counter value that's too small (processor isexecuting too slowly, due to lack of cache or similar) and alwaysinterrupting before execution can continue. Try increasing theTICK_COUNTER_VALUE #define to give the processor time to continue.Julius Baxter, julius@opencores.org*/////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2010 Authors and OPENCORES.ORG //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer. //////// //////// This source file is free software; you can redistribute it //////// and/or modify it under the terms of the GNU Lesser General //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any //////// later version. //////// //////// This source is distributed in the hope that it will be //////// useful, but WITHOUT ANY WARRANTY; without even the implied //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //////// PURPOSE. See the GNU Lesser General Public License for more //////// details. //////// //////// You should have received a copy of the GNU Lesser General //////// Public License along with this source; if not, download it //////// from http://www.opencores.org/lgpl.shtml //////// //////////////////////////////////////////////////////////////////////////#define TICK_COUNTER_VALUE 16/* =================================================== [ exceptions ] === */.section .vectors, "ax"/* ---[ 0x100: RESET exception ]----------------------------------------- */.org 0x100l.movhi r0, 0/* Clear status register */l.ori r1, r0, SPR_SR_SMl.mtspr r0, r1, SPR_SR/* Clear timer */l.mtspr r0, r0, SPR_TTMR/* Init the stack */.global _stackl.movhi r1, hi(_stack)l.ori r1, r1, lo(_stack)l.addi r2, r0, -3l.and r1, r1, r2/* Jump to program initialisation code */.global _startl.movhi r4, hi(_start)l.ori r4, r4, lo(_start)l.jr r4l.nop/* =================================================== [ tick interrupt ] === */.org 0x500.global _tick_handler_tick_handler:l.addi r17, r17, 1# Set r7 to hold value of TTMR, one-shot mode/single run (SR)l.addi r5, r0, TICK_COUNTER_VALUE /* Tick timer counter value */l.movhi r6,hi(SPR_TTMR_SR | SPR_TTMR_IE)l.add r7,r5,r6/* Report values , 0x00000500 == tick timer report*/l.ori r3, r0, 0x0500l.nop 2l.or r3, r0, r17l.nop 2# Init the tick timerl.mtspr r0,r0,SPR_TTCR # clear TTCRl.mtspr r0,r7,SPR_TTMR # set TTMRl.rfe/* ========================================================= [ syscall ] === */.org 0xC00.extern _syscall_function.global _syscall_handler_syscall_handler:l.addi r15, r15, 1l.mfspr r7, r0, SPR_ESR_BASE /* Put ESR in r7, set back to ESR later */l.mfspr r8, r0, SPR_EPCR_BASE/* Put EPCR in r8,set back to EPCR later*//* Unset IEE and TEE bits of SR */l.ori r4, r0, SPR_SR_IEE|SPR_SR_TEEl.ori r5, r0, 0xffffl.xor r5, r5, r4l.and r5, r7, r5 /* New SR without interrupt bits set */l.mtspr r0, r5, SPR_ESR_BASE /* SR after l.rfe *//* Report values , 0x00000c00 == tick timer report*/l.ori r3, r0, 0x0c00l.nop 2/* Get syscall number */l.lwz r3, -4(r8) /* r8 = load(EPCR-4)= PC of l.sys that caused this */l.andi r3, r3, 0xffff /* get 16-bit immediate syscall number */l.nop 2l.movhi r4, hi(_syscall_function)l.ori r4, r4, lo(_syscall_function)l.mtspr r0, r4, SPR_EPCR_BASEl.rfe/* =================================================== [ text section ] === */.section .text/* =================================================== [ start ] === */.global _start_start:/* Instruction cache enable *//* Check if IC present and skip enabling otherwise */l.mfspr r24,r0,SPR_UPRl.andi r26,r24,SPR_UPR_ICPl.sfeq r26,r0l.bf .L8l.nop/* Disable IC */l.mfspr r6,r0,SPR_SRl.addi r5,r0,-1l.xori r5,r5,SPR_SR_ICEl.and r5,r6,r5l.mtspr r0,r5,SPR_SR/* Establish cache block sizeIf BS=0, 16;If BS=1, 32;r14 contain block size*/l.mfspr r24,r0,SPR_ICCFGRl.andi r26,r24,SPR_ICCFGR_CBSl.srli r28,r26,7l.ori r30,r0,16l.sll r14,r30,r28/* Establish number of cache setsr16 contains number of cache setsr28 contains log(# of cache sets)*/l.andi r26,r24,SPR_ICCFGR_NCSl.srli r28,r26,3l.ori r30,r0,1l.sll r16,r30,r28/* Invalidate IC */l.addi r6,r0,0l.sll r5,r14,r28.L7:l.mtspr r0,r6,SPR_ICBIRl.sfne r6,r5l.bf .L7l.add r6,r6,r14/* Enable IC */l.mfspr r6,r0,SPR_SRl.ori r6,r6,SPR_SR_ICEl.mtspr r0,r6,SPR_SRl.nopl.nopl.nopl.nopl.nopl.nopl.nopl.nop.L8:/* Data cache enable *//* Check if DC present and skip enabling otherwise */l.mfspr r24,r0,SPR_UPRl.andi r26,r24,SPR_UPR_DCPl.sfeq r26,r0l.bf .L10l.nop/* Disable DC */l.mfspr r6,r0,SPR_SRl.addi r5,r0,-1l.xori r5,r5,SPR_SR_DCEl.and r5,r6,r5l.mtspr r0,r5,SPR_SR/* Establish cache block sizeIf BS=0, 16;If BS=1, 32;r14 contain block size*/l.mfspr r24,r0,SPR_DCCFGRl.andi r26,r24,SPR_DCCFGR_CBSl.srli r28,r26,7l.ori r30,r0,16l.sll r14,r30,r28/* Establish number of cache setsr16 contains number of cache setsr28 contains log(# of cache sets)*/l.andi r26,r24,SPR_DCCFGR_NCSl.srli r28,r26,3l.ori r30,r0,1l.sll r16,r30,r28/* Invalidate DC */l.addi r6,r0,0l.sll r5,r14,r28.L9:l.mtspr r0,r6,SPR_DCBIRl.sfne r6,r5l.bf .L9l.add r6,r6,r14/* Enable DC */l.mfspr r6,r0,SPR_SRl.ori r6,r6,SPR_SR_DCEl.mtspr r0,r6,SPR_SR.L10:// Kick off testl.jal _mainl.nop/* =================================================== [ main ] === */.global _main_main:l.movhi r15, 0l.movhi r16, 0l.movhi r17, 0## unmask all ints#l.movhi r5,0xffffl.ori r5,r5,0xffffl.mtspr r0,r5,SPR_PICMR # set PICMR# Set r20 to hold enable exceptions and interruptsl.mfspr r20,r0,SPR_SRl.ori r20,r20,SPR_SR_SM|SPR_SR_TEE# Enable exceptions and interruptsl.mtspr r0,r20,SPR_SR # set SR# Set r7 to hold value of TTMR, one-shot mode/single run (SR)l.addi r5, r0, TICK_COUNTER_VALUE /* Tick timer counter value */l.movhi r6,hi(SPR_TTMR_SR | SPR_TTMR_IE)l.add r7,r5,r6# Init the tick timerl.mtspr r0,r0,SPR_TTCR # clear TTCRl.mtspr r0,r7,SPR_TTMR # set TTMR_wait_loop:l.sfeqi r17, 0x10l.bnf _wait_loopl.nop/* Timer is working, let's start with some syscalls *//* These should occur before tick timer's cycle is up */l.nopl.sys 0x1l.nopl.sys 0x2l.nopl.sys 0x3l.nopl.sys 0x4l.nopl.sys 0x5l.nopl.sfnei r16, 0xf /* Should equal 15, 0xf */l.bf _faill.nop/* Continue, hopefuly now intercept tick timer cycles */l.nopl.nopl.sys 0x6l.nopl.nopl.nopl.nopl.sys 0x7l.nopl.nopl.sys 0x8l.nopl.nopl.sys 0x9l.nopl.nopl.sys 0xal.nopl.nopl.nopl.sys 0xbl.nopl.nopl.nopl.nopl.sys 0xcl.nopl.nopl.sys 0xdl.nopl.nopl.sys 0xel.nopl.nopl.sys 0xfl.nop/* Now turn off tick timer */l.mtspr r0,r0,SPR_TTMR # clear TTMRl.sfnei r16, 0x78 /* Should equal 120, 0x78 */l.bf _faill.nopl.movhi r3, hi(0x8000000d)l.ori r3, r3, lo(0x8000000d)l.nop 2l.ori r3, r0, 0l.nop 1_fail:l.movhi r3, hi(0xbaaaaaad)l.ori r3, r3, lo(0xbaaaaaad)l.nop 1.global _syscall_function_syscall_function:/* r7 and r8 hold actual real ESR and EPCR, respectively *//* We'll restore them now */l.mtspr r0, r7, SPR_ESR_BASE /* SR before syscall */l.mtspr r0, r8, SPR_EPCR_BASEl.add r16, r16, r3 /* Add syscall number to our counter */l.movhi r4, hi(0x01000000) /* 16MB mark of memory *//* Ensure memory access OK */l.slli r3, r3, 2 /* Turn syscall number into a word address (<< 2) */l.add r4, r4, r3 /* Access this offset from 16MB mark */l.sw 0(r4), r16 /* Do a write to memory */l.lwz r16, 0(r4) /* Do a read from memory *//* Report running value of syscall counter */l.or r3, r0, r16l.nop 2l.rfe /* Now continue from where we had the l.sys */
