OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/tags/or1ksim/or1ksim-0.3.0/testbench/uos
    from Rev 19 to Rev 21
    Reverse comparison

Rev 19 → Rev 21

/ipc.h
0,0 → 1,27
/* This file is part of test microkernel for OpenRISC 1000. */
/* (C) 2000 Damjan Lampret, lampret@opencores.org */
 
/* Operation completed sucessfully. */
#define IPC_NOERR 0
 
/* Can't send any messages due to lack of free MCBs. */
#define IPC_EOUTOFMCBS 1
 
/* Sending message: No such destination task.
Receiving message: No such origin task. */
#define IPC_ENOTASK 2
 
/* Message to big to be sent or receive buffer is to small for
receiving message. If receiving then try again with bigger buffer. */
#define IPC_ETOOBIG 3
 
/* No messages waiting to be received. */
#define IPC_ENOMSGS 4
 
/* Send message in buffer buf of size len to task desttask. */
int uos_msgsnd(tid_t desttask, char *buf, int len);
 
/* Receive message of max size len from task origintask and put it
into buffer buf. If origintask is zero then get the first message
from the message queue. */
int uos_msgrcv(tid_t origintask, char *buf, int len);
ipc.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: task.c =================================================================== --- task.c (nonexistent) +++ task.c (revision 21) @@ -0,0 +1,54 @@ +/* This file is part of test microkernel for OpenRISC 1000. */ +/* (C) 2000 Damjan Lampret, lampret@opencores.org */ + +#include "support.h" +#include "uos.h" +#include "ipc.h" +#include "int.h" + +extern struct tcb tasks[MAX_TASKS+1]; + +int task(int id) +{ + int rc; + struct _msg { + char id; + unsigned long count; + } msg; + + printf("Task %d started\n", id); + + if(id == 1) { + msg.id = 1; + msg.count = 0; + uos_msgsnd(2, (char *)&msg, sizeof(msg)); + } + + for(;;) { + rc = uos_msgrcv(0, (char *)&msg, sizeof(msg)); + + if(rc != 0) { + printf("Task %d: Waiting for massage\n", id); + } else { + printf("Task %d: Got massage from task %d: 0x%.8x. Sending message to task %d: 0x%.8x \n", id, msg.id, (int)msg.count, (id == 3 ? 1 : (id + 1)), (int)(msg.count + 1)); + msg.id = id; + + if((id == 1) && (msg.count > 15)) { + report(msg.count + 0xdeadde9c); + exit(0); + } + + msg.count += 1; + uos_msgsnd((id == 3 ? 1 : (id + 1)), (char *)&msg, sizeof(msg)); + } + } +} + +/* Called by kernel_init to collect all tasks entries. */ +void tasks_entries() +{ + tasks[1].regs.pc = (unsigned long)task; + tasks[2].regs.pc = (unsigned long)task; + tasks[3].regs.pc = (unsigned long)task; +} +
task.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: uos.c =================================================================== --- uos.c (nonexistent) +++ uos.c (revision 21) @@ -0,0 +1,314 @@ +/* This file is part of test microkernel for OpenRISC 1000. */ +/* (C) 2000 Damjan Lampret, lampret@opencores.org */ + +#include "support.h" +#include "spr_defs.h" +#include "uos.h" +#include "ipc.h" +#include "int.h" + +/* External functions prototypes */ +int tick_init(unsigned long period, void (* inf)(void)); + +/* Pointers to contexts used by except_or32.S routines */ +unsigned long *task_context; +unsigned long *kernel_context; + +/* TCBs for all tasks in the system */ +struct tcb tasks[MAX_TASKS+1]; + +/* Stacks for the tasks (stacks[0] is kernel stack) */ +unsigned char stacks[MAX_TASKS+1][STACK_SIZE]; + +/* MCBs for IPC messages */ +struct mcb msgs[MAX_MSGS]; + +/* Pointer to linked list of free MCBs. */ +struct mcb *free_mcbs; + +/* TID of the current user task */ +tid_t curtask = 0; + +/* Statistics */ +int kernel_sched_cnt = 0; +int kernel_syscall_cnt = 0; + +/* Timestamp via or1ksim (CPU cycle number). */ +unsigned long timestamp() +{ + register unsigned long cycles asm("r3"); + asm("l.sys 201"); + return cycles; +} + +/* Standard function for filling memory with a constant byte. */ +void *memset(void *dst, int c, size_t size) +{ + char *tmp = dst; + + for(;tmp && (tmp < (char *)dst + size); tmp++) + *(char *)tmp = (char)c; + + return dst; +} + +/* Traverse linked list of MCBs and show individual messages. */ +void kernel_show_mcbs(struct mcb *mcb) +{ + for(;mcb; mcb = mcb->next) { + printf("MCB len=%u origintask=%u ", mcb->length, mcb->origin); + printf("msg:%s\n", mcb->msg); + } +} + +/* Show all contexts. */ +void kernel_show_contexts() +{ + int i; + tid_t t; + + for(t = 1; t <= MAX_TASKS; t++) { + printf("\ntask TID=%d: PC=0x%x ", t, (unsigned)tasks[t].regs.pc & ~0x3); + printf("SP(r1)=0x%x ", (unsigned)tasks[t].regs.sp); + printf("SR[IEE]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_IEE); + printf("SR[TEE]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_TEE); + printf("SR[SM]=%d\n", (unsigned)tasks[t].regs.sr & SPR_SR_SM); + for(i = 1; i < GPRS; i++) { + if (i % 4 == 0) + printf("\n"); + printf("r%d=0x%.8x ", i, (unsigned)tasks[t].regs.gprs[i]); + } + printf("\n"); + kernel_show_mcbs(tasks[t].waiting_msgs); + } + printf("\n"); +} + +/* Simple round-robin scheduler that directly calls dispatcher. It is + called by low level external interrupt exception handler or by + kernel_syscall if KERNEL_SYSCALL_SCHED is defined. */ +void kernel_sched() +{ + if ((++curtask > MAX_TASKS) || !(tasks[curtask].regs.pc & ~0x3)) + curtask = 1; + task_context = (unsigned long *)&tasks[curtask].regs; + +#if KERNEL_OUTPUT + printf("kernel_sched(): entry number %d, ", ++kernel_sched_cnt); + printf("dispatching task TID=%d, time %u cycles", curtask, timestamp()); + + kernel_show_contexts(); +#endif + + dispatch(); +} + +/* System call uos_msgsnd. */ +int uos_msgsnd(tid_t desttask, char *buf, int len) +{ + asm("l.sys 1"); + asm("l.nop"); +} + +/* System call uos_msgrcv. */ +int uos_msgrcv(tid_t origintask, char *buf, int len) +{ + asm("l.sys 2"); + asm("l.nop"); +} + +/* Handles system call uos_msgsnd. */ +void kernel_msgsnd(tid_t tid) +{ + struct mcb *mcb; + struct mcb **dstmq; + struct tcb *task; + + task = &tasks[tid]; + + /* Sanity checks. */ + + /* Does destination task exist? */ + if (!task->regs.gprs[1] || (task->regs.gprs[1] > MAX_TASKS)) { + task->regs.gprs[9] = IPC_ENOTASK; + return; + } + + /* Are there any free MCBs? */ + if (!free_mcbs) { + task->regs.gprs[9] = IPC_EOUTOFMCBS; + return; + } + + /* Is message too big to fit into MCB's message buffer? */ + if (task->regs.gprs[3] > MAX_MSGLEN) { + task->regs.gprs[9] = IPC_ETOOBIG; + return; + } + + /* OK, send the message. */ + + /* First, allocate MCB. */ + mcb = free_mcbs; + free_mcbs = mcb->next; + + /* Second, copy message to the MCB. */ + memcpy(mcb->msg, (void *)task->regs.gprs[2], task->regs.gprs[3]); + mcb->origin = tid; + mcb->length = task->regs.gprs[3]; + mcb->next = NULL; + + /* Insert MCB into destination task's message queue at + the end. */ + dstmq = &tasks[task->regs.gprs[1]].waiting_msgs; + for(;*dstmq;) + dstmq = &((*dstmq)->next); + *dstmq = mcb; + + task->regs.gprs[9] = IPC_NOERR; + return; +} + +/* Handles system call uos_msgrcv. */ +void kernel_msgrcv(tid_t tid) +{ + struct mcb *mcb; + struct mcb *curmsg, **linkp; + struct tcb *task; + + task = &tasks[tid]; + + /* Sanity checks. */ + + /* Does origin task exist? */ + if (task->regs.gprs[1] > MAX_TASKS) { + task->regs.gprs[9] = IPC_ENOTASK; + return; + } + + /* Are there any messages waiting for reception? */ + if (!task->waiting_msgs) { + task->regs.gprs[9] = IPC_ENOMSGS; + return; + } + + /* OK, receive the message. */ + + /* Search waiting messages for one coming from origintask. If + origintask is zero then grab the first message. */ + curmsg = task->waiting_msgs; + linkp = &task->waiting_msgs; + for(;task->regs.gprs[1] && curmsg->next && curmsg->origin != task->regs.gprs[1];) { + linkp = &curmsg->next; + curmsg = curmsg->next; + } + + /* Is receive buffer too small for receiving message? */ + if (task->regs.gprs[3] < curmsg->length) { + task->regs.gprs[9] = IPC_ETOOBIG; + return; + } + + /* Now copy the message from the MCB. */ + memcpy((void *)task->regs.gprs[2], curmsg->msg, task->regs.gprs[3]); + + /* Remove MCB from task's waiting queue and place it + back into free MCBs queue. */ + *linkp = curmsg->next; + curmsg->next = free_mcbs; + free_mcbs = curmsg; + + task->regs.gprs[9] = IPC_NOERR; + return; +} + +/* Handles all uOS system calls. It is called by low level system call + exception handler. */ +void kernel_syscall() +{ + unsigned short syscall_num; + +#if KERNEL_OUTPUT + printf("kernel_syscall(): entry number %d, ", ++kernel_syscall_cnt); + printf("current TID=%d, time %u cycles", curtask, timestamp()); + + kernel_show_contexts(); +#endif + syscall_num = *(unsigned short *)((tasks[curtask].regs.pc & ~0x3) - 6); + + switch(syscall_num) { + case IPC_MSGSND: + kernel_msgsnd(curtask); + break; + case IPC_MSGRCV: + kernel_msgrcv(curtask); + break; + default: + printf("kernel_syscall(): unknown syscall (%u)\n", syscall_num); + } + +#if KERNEL_SYSCALL_SCHED + kernel_sched(); +#endif + dispatch(); +} + +/* Called by reset exception handler to initialize the kernel and start + rolling first task. */ +int kernel_init() +{ + tid_t t; + int i; + + printf("Initializing kernel:\n"); + + printf(" Clearing kernel structures...\n"); + memset(tasks, 0, sizeof(tasks)); + memset(stacks, 0, sizeof(stacks)); + memset(msgs, 0, sizeof(msgs)); + + printf(" Initializing MCBs... %d MCB(s)\n", MAX_MSGS); + for(i = 0; i < (MAX_MSGS - 1); i++) + msgs[i].next = &msgs[i+1]; + free_mcbs = &msgs[0]; + + printf(" Initializing TCBs... %d user task(s)\n", MAX_TASKS); + + tasks_entries(); + + for(t = 0; t <= MAX_TASKS; t++) { + tasks[t].regs.sp = (unsigned long)stacks[t] + STACK_SIZE - 4; + /* Disable EXR for kernel context */ + tasks[t].regs.sr |= (t == 0 ? SPR_SR_SM : SPR_SR_TEE | SPR_SR_IEE); + tasks[t].regs.gprs[1] = t; + } + + /* First task runs in seprvisor mode */ + tasks[1].regs.sr |= SPR_SR_SM; + + /* TID=0 is reserved for kernel use */ + kernel_context = (unsigned long *)&tasks[0].regs; + + /* First task to be scheduled is task TID=1 */ + task_context = (unsigned long *)&tasks[1].regs; + + /* Initialize initrrupt controller */ + int_init(); + + printf(" Exceptions will be enabled when first task is dispatched.\n"); + printf("Kernel initalized. Starting first user task.\n"); + +#if KERNEL_SYSCALL_SCHED + kernel_sched(); /* Lets schedule and dispatch our first task */ +#else + tick_init(TICK_PERIOD, kernel_sched); + kernel_sched(); /* Lets schedule and dispatch our first task */ +#endif + /* ... */ /* We never get here */ +} + +int main () +{ + kernel_init(); + return 0; +}
uos.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: Makefile.am =================================================================== --- Makefile.am (nonexistent) +++ Makefile.am (revision 21) @@ -0,0 +1,28 @@ +## Makefile for or1ksim subdirectory test +## (c) Marko Mlinar, 2001 +## To add new test, edit between marked areas only +# +# This file is part of OpenRISC 1000 Architectural Simulator. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +LDADD = ../support/libsupport.a +LDFLAGS = -T${top_srcdir}/default.ld + +bin_PROGRAMS = uos +uos_SOURCES = except_or32.S support.h spr_defs.h task.c int.h ipc.h tick.c uos.h uos.c + +again: clean all
Makefile.am Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: spr_defs.h =================================================================== --- spr_defs.h (nonexistent) +++ spr_defs.h (revision 21) @@ -0,0 +1,428 @@ +/* spr_defs.h -- Defines OR1K architecture specific special-purpose registers + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + +This file is part of OpenRISC 1000 Architectural Simulator. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file is also used by microkernel test bench. Among +others it is also used in assembly file(s). */ + +/* Definition of special-purpose registers (SPRs) */ + +#define MAX_GRPS (32) +#define MAX_SPRS_PER_GRP_BITS (11) +#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS) +#define MAX_SPRS (0x10000) + +/* Base addresses for the groups */ +#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS) + +/* System control and status group */ +#define SPR_VR (SPRGROUP_SYS + 0) +#define SPR_UPR (SPRGROUP_SYS + 1) +#define SPR_CPUCFGR (SPRGROUP_SYS + 2) +#define SPR_DMMUCFGR (SPRGROUP_SYS + 3) +#define SPR_IMMUCFGR (SPRGROUP_SYS + 4) +#define SPR_DCCFGR (SPRGROUP_SYS + 5) +#define SPR_ICCFGR (SPRGROUP_SYS + 6) +#define SPR_DCFGR (SPRGROUP_SYS + 7) +#define SPR_PCCFGR (SPRGROUP_SYS + 8) +#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */ +#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */ +#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */ +#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */ +#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */ +#define SPR_EEAR_BASE (SPRGROUP_SYS + 48) +#define SPR_EEAR_LAST (SPRGROUP_SYS + 63) +#define SPR_ESR_BASE (SPRGROUP_SYS + 64) +#define SPR_ESR_LAST (SPRGROUP_SYS + 79) + +/* Data MMU group */ +#define SPR_DMMUCR (SPRGROUP_DMMU + 0) +#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x200) +#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x200) +#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x300 + (WAY) * 0x200) +#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x3ff + (WAY) * 0x200) + +/* Instruction MMU group */ +#define SPR_IMMUCR (SPRGROUP_IMMU + 0) +#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x200) +#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x200) +#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x300 + (WAY) * 0x200) +#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x3ff + (WAY) * 0x200) + +/* Data cache group */ +#define SPR_DCCR (SPRGROUP_DC + 0) +#define SPR_DCBPR (SPRGROUP_DC + 1) +#define SPR_DCBFR (SPRGROUP_DC + 2) +#define SPR_DCBIR (SPRGROUP_DC + 3) +#define SPR_DCBWR (SPRGROUP_DC + 4) +#define SPR_DCBLR (SPRGROUP_DC + 5) +#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200) +#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200) + +/* Instruction cache group */ +#define SPR_ICCR (SPRGROUP_IC + 0) +#define SPR_ICBPR (SPRGROUP_IC + 1) +#define SPR_ICBIR (SPRGROUP_IC + 2) +#define SPR_ICBLR (SPRGROUP_IC + 3) +#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200) +#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200) + +/* MAC group */ +#define SPR_MACLO (SPRGROUP_MAC + 1) +#define SPR_MACHI (SPRGROUP_MAC + 2) + +/* Debug group */ +#define SPR_DVR(N) (SPRGROUP_D + (N)) +#define SPR_DCR(N) (SPRGROUP_D + 8 + (N)) +#define SPR_DMR1 (SPRGROUP_D + 16) +#define SPR_DMR2 (SPRGROUP_D + 17) +#define SPR_DWCR0 (SPRGROUP_D + 18) +#define SPR_DWCR1 (SPRGROUP_D + 19) +#define SPR_DSR (SPRGROUP_D + 20) +#define SPR_DRR (SPRGROUP_D + 21) + +/* Performance counters group */ +#define SPR_PCCR(N) (SPRGROUP_PC + (N)) +#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N)) + +/* Power management group */ +#define SPR_PMR (SPRGROUP_PM + 0) + +/* PIC group */ +#define SPR_PICMR (SPRGROUP_PIC + 0) +#define SPR_PICPR (SPRGROUP_PIC + 1) +#define SPR_PICSR (SPRGROUP_PIC + 2) + +/* Tick Timer group */ +#define SPR_TTMR (SPRGROUP_TT + 0) +#define SPR_TTCR (SPRGROUP_TT + 1) + +/* + * Bit definitions for the Version Register + * + */ +#define SPR_VR_VER 0xffff0000 /* Processor version */ +#define SPR_VR_REV 0x0000003f /* Processor revision */ + +/* + * Bit definitions for the Unit Present Register + * + */ +#define SPR_UPR_UP 0x00000001 /* UPR present */ +#define SPR_UPR_DCP 0x00000002 /* Data cache present */ +#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */ +#define SPR_UPR_DMP 0x00000008 /* Data MMU present */ +#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */ +#define SPR_UPR_OB32P 0x00000020 /* ORBIS32 present */ +#define SPR_UPR_OB64P 0x00000040 /* ORBIS64 present */ +#define SPR_UPR_OF32P 0x00000080 /* ORFPX32 present */ +#define SPR_UPR_OF64P 0x00000100 /* ORFPX64 present */ +#define SPR_UPR_OV32P 0x00000200 /* ORVDX32 present */ +#define SPR_UPR_OV64P 0x00000400 /* ORVDX64 present */ +#define SPR_UPR_DUP 0x00000800 /* Debug unit present */ +#define SPR_UPR_PCUP 0x00001000 /* Performance counters unit present */ +#define SPR_UPR_PMP 0x00002000 /* Power management present */ +#define SPR_UPR_PICP 0x00004000 /* PIC present */ +#define SPR_UPR_TTP 0x00008000 /* Tick timer present */ +#define SPR_UPR_SRP 0x00010000 /* Shadow registers present */ +#define SPR_UPR_RES 0x00fe0000 /* ORVDX32 present */ +#define SPR_UPR_CUST 0xff000000 /* Custom units */ + +/* + * Bit definitions for the Supervision Register + * + */ +#define SPR_SR_CID 0xf0000000 /* Context ID */ +#define SPR_SR_FO 0x00008000 /* Fixed one */ +#define SPR_SR_EPH 0x00004000 /* Exception Prefixi High */ +#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */ +#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */ +#define SPR_SR_OV 0x00000800 /* Overflow flag */ +#define SPR_SR_CY 0x00000400 /* Carry flag */ +#define SPR_SR_F 0x00000200 /* Condition Flag */ +#define SPR_SR_CE 0x00000100 /* CID Enable */ +#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */ +#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */ +#define SPR_SR_DME 0x00000020 /* Data MMU Enable */ +#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */ +#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */ +#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */ +#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */ +#define SPR_SR_SM 0x00000001 /* Supervisor Mode */ + +/* + * Bit definitions for the Data MMU Control Register + * + */ +#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */ +#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ +#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ +#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ + +/* + * Bit definitions for the Instruction MMU Control Register + * + */ +#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */ +#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ +#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ +#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ + +/* + * Bit definitions for the Data TLB Match Register + * + */ +#define SPR_DTLBMR_V 0x00000001 /* Valid */ +#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ +#define SPR_DTLBMR_CID 0x0000003c /* Context ID */ +#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */ +#define SPR_DTLBMR_VPN 0xfffff000 /* Virtual Page Number */ + +/* + * Bit definitions for the Data TLB Translate Register + * + */ +#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */ +#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */ +#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */ +#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ +#define SPR_DTLBTR_A 0x00000010 /* Accessed */ +#define SPR_DTLBTR_D 0x00000020 /* Dirty */ +#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */ +#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */ +#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */ +#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */ +#define SPR_DTLBTR_PPN 0xfffff000 /* Physical Page Number */ + +/* + * Bit definitions for the Instruction TLB Match Register + * + */ +#define SPR_ITLBMR_V 0x00000001 /* Valid */ +#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ +#define SPR_ITLBMR_CID 0x0000003c /* Context ID */ +#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */ +#define SPR_ITLBMR_VPN 0xfffff000 /* Virtual Page Number */ + +/* + * Bit definitions for the Instruction TLB Translate Register + * + */ +#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */ +#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */ +#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */ +#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ +#define SPR_ITLBTR_A 0x00000010 /* Accessed */ +#define SPR_ITLBTR_D 0x00000020 /* Dirty */ +#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */ +#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */ +#define SPR_ITLBTR_PPN 0xfffff000 /* Physical Page Number */ + +/* + * Bit definitions for Data Cache Control register + * + */ +#define SPR_DCCR_EW 0x000000ff /* Enable ways */ + +/* + * Bit definitions for Insn Cache Control register + * + */ +#define SPR_ICCR_EW 0x000000ff /* Enable ways */ + +/* + * Bit definitions for Debug Control registers + * + */ +#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */ +#define SPR_DCR_CC 0x0000000e /* Compare condition */ +#define SPR_DCR_SC 0x00000010 /* Signed compare */ +#define SPR_DCR_CT 0x000000e0 /* Compare to */ + +/* Bit results with SPR_DCR_CC mask */ +#define SPR_DCR_CC_MASKED 0x00000000 +#define SPR_DCR_CC_EQUAL 0x00000001 +#define SPR_DCR_CC_LESS 0x00000002 +#define SPR_DCR_CC_LESSE 0x00000003 +#define SPR_DCR_CC_GREAT 0x00000004 +#define SPR_DCR_CC_GREATE 0x00000005 +#define SPR_DCR_CC_NEQUAL 0x00000006 + +/* Bit results with SPR_DCR_CT mask */ +#define SPR_DCR_CT_DISABLED 0x00000000 +#define SPR_DCR_CT_IFEA 0x00000020 +#define SPR_DCR_CT_LEA 0x00000040 +#define SPR_DCR_CT_SEA 0x00000060 +#define SPR_DCR_CT_LD 0x00000080 +#define SPR_DCR_CT_SD 0x000000a0 +#define SPR_DCR_CT_LSEA 0x000000c0 + +/* + * Bit definitions for Debug Mode 1 register + * + */ +#define SPR_DMR1_CW0 0x00000003 /* Chain watchpoint 0 */ +#define SPR_DMR1_CW1 0x0000000c /* Chain watchpoint 1 */ +#define SPR_DMR1_CW2 0x00000030 /* Chain watchpoint 2 */ +#define SPR_DMR1_CW3 0x000000c0 /* Chain watchpoint 3 */ +#define SPR_DMR1_CW4 0x00000300 /* Chain watchpoint 4 */ +#define SPR_DMR1_CW5 0x00000c00 /* Chain watchpoint 5 */ +#define SPR_DMR1_CW6 0x00003000 /* Chain watchpoint 6 */ +#define SPR_DMR1_CW7 0x0000c000 /* Chain watchpoint 7 */ +#define SPR_DMR1_CW8 0x00030000 /* Chain watchpoint 8 */ +#define SPR_DMR1_CW9 0x000c0000 /* Chain watchpoint 9 */ +#define SPR_DMR1_CW10 0x00300000 /* Chain watchpoint 10 */ +#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/ +#define SPR_DMR1_BT 0x00800000 /* Branch trace */ +#define SPR_DMR1_DXFW 0x01000000 /* Disable external force watchpoint */ + +/* + * Bit definitions for Debug Mode 2 register + * + */ +#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */ +#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */ +#define SPR_DMR2_AWTC 0x00001ffc /* Assign watchpoints to counters */ +#define SPR_DMR2_WGB 0x00ffe000 /* Watchpoints generating breakpoint */ + +/* + * Bit definitions for Debug watchpoint counter registers + * + */ +#define SPR_DWCR_COUNT 0x0000ffff /* Count */ +#define SPR_DWCR_MATCH 0xffff0000 /* Match */ + +/* + * Bit definitions for Debug stop register + * + */ +#define SPR_DSR_RSTE 0x00000001 /* Reset exception */ +#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */ +#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */ +#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */ +#define SPR_DSR_TTE 0x00000010 /* iTick Timer exception */ +#define SPR_DSR_AE 0x00000020 /* Alignment exception */ +#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */ +#define SPR_DSR_IE 0x00000080 /* Interrupt exception */ +#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */ +#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */ +#define SPR_DSR_RE 0x00000400 /* Range exception */ +#define SPR_DSR_SCE 0x00000800 /* System call exception */ +#define SPR_DSR_SSE 0x00001000 /* Single Step Exception */ +#define SPR_DSR_TE 0x00002000 /* Trap exception */ + +/* + * Bit definitions for Debug reason register + * + */ +#define SPR_DRR_RSTE 0x00000001 /* Reset exception */ +#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */ +#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */ +#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */ +#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */ +#define SPR_DRR_AE 0x00000020 /* Alignment exception */ +#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */ +#define SPR_DRR_IE 0x00000080 /* Interrupt exception */ +#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */ +#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */ +#define SPR_DRR_RE 0x00000400 /* Range exception */ +#define SPR_DRR_SCE 0x00000800 /* System call exception */ +#define SPR_DRR_TE 0x00001000 /* Trap exception */ + +/* + * Bit definitions for Performance counters mode registers + * + */ +#define SPR_PCMR_CP 0x00000001 /* Counter present */ +#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */ +#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */ +#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */ +#define SPR_PCMR_LA 0x00000010 /* Load access event */ +#define SPR_PCMR_SA 0x00000020 /* Store access event */ +#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/ +#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */ +#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */ +#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */ +#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */ +#define SPR_PCMR_BS 0x00000800 /* Branch stall event */ +#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */ +#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */ +#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */ +#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */ + +/* + * Bit definitions for the Power management register + * + */ +#define SPR_PMR_SDF 0x0000000f /* Slow down factor */ +#define SPR_PMR_DME 0x00000010 /* Doze mode enable */ +#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */ +#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */ +#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */ + +/* + * Bit definitions for PICMR + * + */ +#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */ + +/* + * Bit definitions for PICPR + * + */ +#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */ + +/* + * Bit definitions for PICSR + * + */ +#define SPR_PICSR_IS 0xffffffff /* Interrupt status */ + +/* + * Bit definitions for Tick Timer Control Register + * + */ +#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */ +#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD +#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */ +#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */ +#define SPR_TTMR_RT 0x40000000 /* Restart tick */ +#define SPR_TTMR_SR 0x80000000 /* Single run */ +#define SPR_TTMR_CR 0xc0000000 /* Continuous run */ +#define SPR_TTMR_M 0xc0000000 /* Tick mode */ + +/* + * l.nop constants + * + */ +#define NOP_NOP 0x0000 /* Normal nop instruction */ +#define NOP_EXIT 0x0001 /* End of simulation */ +#define NOP_REPORT 0x0002 /* Simple report */ +#define NOP_printf 0x0003 /* Simprintf instruction */ +#define NOP_REPORT_FIRST 0x0400 /* Report with number */ +#define NOP_REPORT_LAST 0x03ff /* Report with number */
spr_defs.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: tick.c =================================================================== --- tick.c (nonexistent) +++ tick.c (revision 21) @@ -0,0 +1,34 @@ +/* This file is part of test microkernel for OpenRISC 1000. */ +/* (C) 2001 Simon Srot, srot@opencores.org */ + +#include "spr_defs.h" +#include "support.h" + +/* Tick timer period */ +unsigned long tick_period; + +/* Inform of tick interrupt */ +void (*tick_inf)(); + +/* Tick interrupt routine */ +void tick_int() +{ + /* Call inf routine */ + (*tick_inf)(); + + /* Set new counter period iand clear inet pending bit */ + mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (tick_period & SPR_TTMR_PERIOD)); +} + +/* Initialize routine */ +int tick_init(unsigned long period, void (* inf)()) +{ + /* Save tick timer period and inform routine */ + tick_period = period; + tick_inf = inf; + + /* Set counter period, enable timer and interrupt */ + mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT | (period & SPR_TTMR_PERIOD)); + + return 0; +}
tick.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: uos.h =================================================================== --- uos.h (nonexistent) +++ uos.h (revision 21) @@ -0,0 +1,58 @@ +/* This file is part of test microkernel for OpenRISC 1000. */ +/* (C) 2000 Damjan Lampret, lampret@opencores.org */ + +/* Length of the IPC message's useful data. */ +#define MAX_MSGLEN 100 + +/* Number of user tasks in the system. */ +#define MAX_TASKS 8 + +/* Number of IPC messages in the system. */ +#define MAX_MSGS 16 + +/* Number of general purpose registers (not counting r0 and r1). */ +#define GPRS 30 + +/* Size of kernel and user task stacks. Size for individual task. */ +#define STACK_SIZE 2048 + +/* Define this if you want kernel debug output. Note that you must + assemble except_or32.S with KERNEL_OUTPUT defined in Makefile. This + definition is only for main uos.c. */ +#define KERNEL_OUTPUT 0 + +/* Define this if you want task switch at every system call. */ +#define KERNEL_SYSCALL_SCHED 0 + +/* System tick timer period */ +#define TICK_PERIOD 0x500 + +/* Task ID type (if we would have processes then we would call it PID) */ +typedef int tid_t; + +/* System call numbers */ +#define IPC_MSGSND 1 +#define IPC_MSGRCV 2 + +/* Message Control Block structure */ +struct mcb { + char msg[MAX_MSGLEN]; /* Message's data */ + int length; /* Message's length */ + tid_t origin; /* TID of message's origin task */ + struct mcb *next; /* Next message in linked list */ +}; + +/* Task Control Block structure */ +struct tcb { + struct regs { + unsigned long pc; /* Task's PC */ + unsigned long sp; /* Task's stack (r1)*/ + unsigned long gprs[GPRS]; /* Task's GPRs r2-r15 */ + unsigned long sr; /* Task's supervision register */ + } regs; + struct mcb *waiting_msgs; /* Waiting messages */ +}; + +extern void dispatch(); +/* Called by kernel_init to collect all tasks entries. */ +extern void tasks_entries();
uos.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: .cvsignore =================================================================== --- .cvsignore (nonexistent) +++ .cvsignore (revision 21) @@ -0,0 +1,3 @@ +Makefile +uos +.deps Index: README =================================================================== --- README (nonexistent) +++ README (revision 21) @@ -0,0 +1,18 @@ + +This is the Micro OS (uOS) for testing operating system features of +OpenRISC 1000 architecture. Specifically non reentrant, preemptive +multitasking microkernel. Purpose of this code is not to be a true +operating system but merely a testbench for testing the architecture, +or1ksim and software development tools (GCC, Binutils, ...). + +This test OS has all necessary exception handlers to handle exceptions. There +are two tasks: one task generates data and passes that data via IPC to the +second task. Second task outputs the data via or1ksim syscall to the simulator. + +Currently only OR32 is supported (exception handlers are written in +assembly). Tools required to compile sources are the latest +or32-coff-gcc, or32-coff-as and or32-coff-ld. Also make sure you undefine +VIRTUAL_MACHINE_ONLY when compiling or1ksim. + +-- +10/Jun/2000, Damjan Lampret, lampret@opencores.org
README Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: except_or32.S =================================================================== --- except_or32.S (nonexistent) +++ except_or32.S (revision 21) @@ -0,0 +1,351 @@ +/* This file is part of test microkernel for OpenRISC 1000. */ +/* (C) 2000 Damjan Lampret, lampret@opencores.org */ + +#include "spr_defs.h" +#include "../board.h" + +#define MC_CSR (0x00) +#define MC_POC (0x04) +#define MC_BA_MASK (0x08) +#define MC_CSC(i) (0x10 + (i) * 8) +#define MC_TMS(i) (0x14 + (i) * 8) + + +/* + * Context is saved to area pointed by pointer in R3. Original + * R3 is at memory location 0 and task's PC is at memory location 4. + */ +#define SAVEREGS \ + l.lwz r3,0(r3); \ + l.sw 4(r3),r1; \ + l.sw 8(r3),r2; \ + l.lwz r2,0(r0); /* saving original r3*/ \ + l.sw 12(r3),r2; \ + l.sw 16(r3),r4; \ + l.sw 20(r3),r5; \ + l.sw 24(r3),r6; \ + l.sw 28(r3),r7; \ + l.sw 32(r3),r8; \ + l.sw 36(r3),r9; \ + l.sw 40(r3),r10; \ + l.sw 44(r3),r11; \ + l.sw 48(r3),r12; \ + l.sw 52(r3),r13; \ + l.sw 56(r3),r14; \ + l.sw 60(r3),r15; \ + l.sw 64(r3),r16; \ + l.sw 68(r3),r17; \ + l.sw 72(r3),r18; \ + l.sw 76(r3),r19; \ + l.sw 80(r3),r20; \ + l.sw 84(r3),r21; \ + l.sw 88(r3),r22; \ + l.sw 92(r3),r23; \ + l.sw 96(r3),r24; \ + l.sw 100(r3),r25; \ + l.sw 104(r3),r26; \ + l.sw 108(r3),r27; \ + l.sw 112(r3),r28; \ + l.sw 116(r3),r29; \ + l.sw 120(r3),r30; \ + l.sw 124(r3),r31; \ + l.lwz r2,4(r0); /* saving original PC*/ \ + l.sw 0(r3),r2; \ + \ + l.mfspr r2,r0,SPR_ESR_BASE; \ + l.sw 128(r3),r2 /* saving SR */ + +/* + * Pointer to context is in R3. All registers are loaded and execution is + * transfered to the loaded context's task + */ +#define LOADREGS_N_GO \ + l.lwz r3,0(r3); \ + l.lwz r2,0(r3); /* prepare PC*/ \ + l.mtspr r0,r2,SPR_EPCR_BASE; \ + \ + l.lwz r2,128(r3); /* prepare SR*/ \ + l.mtspr r0,r2,SPR_ESR_BASE; \ + \ + l.lwz r1,4(r3); \ + l.lwz r2,8(r3); \ + l.lwz r4,16(r3); \ + l.lwz r5,20(r3); \ + l.lwz r6,24(r3); \ + l.lwz r7,28(r3); \ + l.lwz r8,32(r3); \ + l.lwz r9,36(r3); \ + l.lwz r10,40(r3); \ + l.lwz r11,44(r3); \ + l.lwz r12,48(r3); \ + l.lwz r13,52(r3); \ + l.lwz r14,56(r3); \ + l.lwz r15,60(r3); \ + l.lwz r16,64(r3); \ + l.lwz r17,68(r3); \ + l.lwz r18,72(r3); \ + l.lwz r19,76(r3); \ + l.lwz r20,80(r3); \ + l.lwz r21,84(r3); \ + l.lwz r22,88(r3); \ + l.lwz r23,92(r3); \ + l.lwz r24,96(r3); \ + l.lwz r25,100(r3); \ + l.lwz r26,104(r3); \ + l.lwz r27,108(r3); \ + l.lwz r28,112(r3); \ + l.lwz r29,116(r3); \ + l.lwz r30,120(r3); \ + l.lwz r31,124(r3); \ + \ + l.lwz r3,12(r3); /* prepare r3*/ \ + \ + l.rfe; /* Call task */ \ + l.nop + +/* + * All registers are loaded from save area. + */ +#define LOADREGS \ + l.lwz r3,0(r3); \ + l.lwz r2,0(r3); /* prepare PC*/ \ + l.mtspr r0,r2,SPR_EPCR_BASE; \ + \ + l.lwz r2,128(r3); /* prepare SR*/ \ + l.mtspr r0,r2,SPR_ESR_BASE; \ + \ + l.lwz r1,4(r3); \ + l.lwz r2,8(r3); \ + l.lwz r4,16(r3); \ + l.lwz r5,20(r3); \ + l.lwz r6,24(r3); \ + l.lwz r7,28(r3); \ + l.lwz r8,32(r3); \ + l.lwz r9,36(r3); \ + l.lwz r10,40(r3); \ + l.lwz r11,44(r3); \ + l.lwz r12,48(r3); \ + l.lwz r13,52(r3); \ + l.lwz r14,56(r3); \ + l.lwz r15,60(r3); \ + l.lwz r16,64(r3); \ + l.lwz r17,68(r3); \ + l.lwz r18,72(r3); \ + l.lwz r19,76(r3); \ + l.lwz r20,80(r3); \ + l.lwz r21,84(r3); \ + l.lwz r22,88(r3); \ + l.lwz r23,92(r3); \ + l.lwz r24,96(r3); \ + l.lwz r25,100(r3); \ + l.lwz r26,104(r3); \ + l.lwz r27,108(r3); \ + l.lwz r28,112(r3); \ + l.lwz r29,116(r3); \ + l.lwz r30,120(r3); \ + l.lwz r31,124(r3); \ + \ + l.lwz r3,12(r3); /* prepare r3*/ + +/* + * Set new PC in saved context + */ +#define SET_CONTEXTPC(AREA,SUBROUTINE,TMPREG) \ + l.lwz AREA,0(AREA); \ + l.movhi TMPREG,hi(SUBROUTINE); \ + l.addi TMPREG,r0,lo(SUBROUTINE); \ + l.sw 0(AREA),TMPREG; + +/* + * Printf via or1ksim hook + */ +#if KERNEL_OUTPUT +#define PRINTF(REG,STR) \ + l.movhi REG,hi(STR); \ + l.addi REG,r0,lo(STR); \ + l.nop NOP_PRINTF +#else +#define PRINTF(REG,STR) +#endif + +/* + * Reset Exception handler + */ +.org 0x100 +_reset_vector: + + l.movhi r3,hi(MC_BASE_ADDR) + l.ori r3,r3,lo(MC_BASE_ADDR) + + l.addi r4,r3,MC_CSC(0) + l.movhi r5,hi(FLASH_BASE_ADDR) + l.srai r5,r5,6 + l.ori r5,r5,0x0025 + l.sw 0(r4),r5 + + l.addi r4,r3,MC_TMS(0) + l.movhi r5,hi(FLASH_TMS_VAL) + l.ori r5,r5,lo(FLASH_TMS_VAL) + l.sw 0(r4),r5 + + l.addi r4,r3,MC_BA_MASK + l.addi r5,r0,MC_MASK_VAL + l.sw 0(r4),r5 + + l.addi r4,r3,MC_CSR + l.movhi r5,hi(MC_CSR_VAL) + l.ori r5,r5,lo(MC_CSR_VAL) + l.sw 0(r4),r5 + + l.addi r4,r3,MC_TMS(1) + l.movhi r5,hi(SDRAM_TMS_VAL) + l.ori r5,r5,lo(SDRAM_TMS_VAL) + l.sw 0(r4),r5 + + l.addi r4,r3,MC_CSC(1) + l.movhi r5,hi(SDRAM_BASE_ADDR) + l.srai r5,r5,6 + l.ori r5,r5,0x0411 + l.sw 0(r4),r5 + + l.jr r9 + l.nop + + /* Copy data section */ + l.movhi r3,hi(_src_beg) + l.ori r3,r3,lo(_src_beg) + l.addi r4,r0,0x200 + l.movhi r5,hi(_except_end) + l.ori r5,r5,lo(_except_end) + l.movhi r6,hi(_except_beg) + l.ori r6,r6,lo(_except_beg) + l.sub r5,r6,r5 +1: + l.lwz r6,0(r3) + l.sw 0(r4),r6 + l.addi r3,r3,4 + l.addi r4,r4,4 + l.addi r5,r5,-4 + l.sfgtsi r5,0 + l.bf 1b + l.nop + + l.movhi r4,hi(_dst_beg) + l.ori r4,r4,lo(_dst_beg) + l.movhi r5,hi(_dst_end) + l.ori r5,r5,lo(_dst_end) + l.sub r5,r5,r4 + l.sfeqi r5,0 + l.bf 2f + l.nop +1: + l.lwz r6,0(r3) + l.sw 0(r4),r6 + l.addi r3,r3,4 + l.addi r4,r4,4 + l.addi r5,r5,-4 + l.sfgtsi r5,0 + l.bf 1b + l.nop + +2: + + + l.movhi r2,hi(_reset) + l.ori r2,r2,lo(_reset) + l.jr r2 + l.nop + +/* + * Switch to a new context pointed by _task_context + */ +.global _dispatch +.align 4 +_dispatch: + /* load user task GPRs and PC */ + l.movhi r3,hi(_task_context) + l.addi r3,r0,lo(_task_context) + LOADREGS_N_GO + +.section .except, "ax" + +/* + * Bus Error Exception handler + */ +.org 0x0200 +_buserr: + l.nop + l.sw 0(r0),r3 /* Save r3 */ + PRINTF(r3, _buserr_str) +_hang: + l.j _hang + l.nop + +_buserr_str: + .ascii "Bus error exception.\n\000" + +/* + * External Interrupt Exception handler + */ +.org 0x800 +_extint: + l.nop + l.sw 0(r0),r3 /* Save r3 */ + PRINTF(r3,_extint_str) + l.mfspr r3,r0,SPR_EPCR_BASE /* Get EPCR */ + l.sw 4(r0),r3 /* and save it */ + + /* now save user task context */ + l.movhi r3,hi(_task_context) + l.addi r3,r0,lo(_task_context) + SAVEREGS + + /* set kernel context's PC to kernel's scheduler */ + l.movhi r3,hi(_kernel_context) + l.addi r3,r0,lo(_kernel_context) + SET_CONTEXTPC(r3,_int_main,r4) + + /* load kernel context */ + l.movhi r3,hi(_kernel_context) + l.addi r3,r0,lo(_kernel_context) + LOADREGS + + l.movhi r3,hi(_int_main) + l.addi r3,r0,lo(_int_main) + l.jr r3 + l.nop + +_extint_str: + .ascii "External interrupt exception.\n\000" + +/* + * System Call Exception handler + */ +.org 0x0c00 +_syscall: + l.nop + l.sw 0(r0),r3 /* Save r3 */ + PRINTF(r3,_syscall_str) + l.mfspr r3,r0,SPR_EPCR_BASE /* Get EPCR */ + l.addi r3,r3,4 /* increment because EPCR instruction was already executed */ + l.sw 4(r0),r3 /* and save it */ + + /* now save user task context */ + l.movhi r3,hi(_task_context) + l.addi r3,r0,lo(_task_context) + SAVEREGS + + /* set kernel context's PC to kernel's syscall entry */ + l.movhi r3,hi(_kernel_context) + l.addi r3,r0,lo(_kernel_context) + SET_CONTEXTPC(r3,_kernel_syscall,r4) + + /* load kernel context */ + l.movhi r3,hi(_kernel_context) + l.addi r3,r0,lo(_kernel_context) + LOADREGS_N_GO + +_syscall_str: + .ascii "System call exception.\n\000" + +
except_or32.S Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.