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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ucos-ii/] [2.91/] [ucos-port/] [os_cpu_a.S] - Blame information for rev 526

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 471 julius
/*
2
----------------------------------------------------------------------
3
    CHiPES Embedded RTR Systems Copyright (c) Tim Oliver 2002-2004
4
----------------------------------------------------------------------
5
 File   : os_cpu_a.S
6
 Author(s) :    Tim Oliver, timtimoliver@yahoo.co.uk
7
                Julius Baxter, julius@opencores.org
8
---------------------------[Description]------------------------------
9
        Start up file for OpenRISC Reference Platform
10
        Assembly code required for ORP port of MicroC/OS-II
11
 
12
        Macros :
13
         exception_vector name org
14
                load32i reg const
15
                store_context
16
                restore_context
17
 
18
        Internal Routines :
19
                _reset          Boot code installed at interrupt vector 0x100
20
                _start          Start up sequence
21
 
22 526 julius
                _OSTickISR      Operating system timer tick interrupt service
23
                                routine
24
                _OSStartHighRdy Starts the highest priority task that is
25
                                available to run
26 471 julius
                _OSCtxSwBP
27
                _OSCtxSw        Task switch
28
                _OSIntCtxSw     Task switch after interrupt
29 526 julius
                _UserISR        Interrupt service routine template - requires
30
                                code
31
                _align          Attempts to recover from memory alignment
32
                                errors
33 471 julius
                nest_not_one
34
 
35
        External Routines       :
36
                _OSIntExit
37
                _OSTimeTick
38
                _OSTaskSwHook
39
 
40
        External variables      :
41
                _OSIntNesting
42
                _OSRunning
43
                _OSPrioHighRdy
44
                _OSPrioCur
45
                _OSTCBCur
46
                _OSTCBHighRdy
47
 
48
        Interrupt Vectors Installed:
49
                0x100   _reset
50
                0x500   _OSTickISR
51
                0x600   _align
52
 
53
                0x800   _UserISR
54
 
55
                0xc00   _OSCtxSw
56
*/
57
 
58
/*
59
This program is free software; you can redistribute it and/or modify
60
it under the terms of the GNU General Public License as published by
61
the Free Software Foundation; either version 2 of the License, or
62
(at your option) any later version.
63
 
64
This program is distributed in the hope that it will be useful,
65
but WITHOUT ANY WARRANTY; without even the implied warranty of
66
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
67
GNU General Public License for more details.
68
 
69
You should have received a copy of the GNU General Public License
70
along with this program; if not, write to the Free Software
71
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
72
*/
73
 
74
#include "spr-defs.h"
75
#include "board.h"
76
 
77
#define RED_ZONE_SIZE 128
78
#define STK_FRAME_SIZE (128+RED_ZONE_SIZE)
79 526 julius
#define SPR_TTMR_LOAD  (SPR_TTMR_IE | SPR_TTMR_RT | \
80
        ((IN_CLK/TICKS_PER_SEC) & SPR_TTMR_PERIOD))
81 471 julius
 
82
/* function prototypes */
83
 
84
        .global  OSTickISR      /* internal functions */
85
        .global  OSStartHighRdy
86
        .global  OSCtxSwBP
87
        .global  OSCtxSw
88
        .global  OSIntCtxSw
89
        .global  UserISR
90
        .global  _align
91
        .global  nest_not_one
92
 
93
        .extern  OSIntExit      /* external functions */
94
        .extern  OSTimeTick
95
        .extern  OSTaskSwHook
96
 
97
        .extern  OSIntNesting   /* values */
98
        .extern  OSRunning
99
        .extern  OSPrioHighRdy
100
        .extern  OSPrioCur
101
        .extern  OSTCBCur
102
        .extern  OSTCBHighRdy
103
 
104
/* Macro Definitions */
105
/* Utility macro: Load a 32-bit constant into a register */
106
        .macro  load32i reg const
107
        l.movhi \reg,hi(\const)
108
        l.ori   \reg,\reg,lo(\const)
109
        .endm
110
 
111
/* Utility macro: Start code for an exception handler */
112
        .macro exception_vector name
113
        l.addi  r1,r1,-STK_FRAME_SIZE
114
        l.sw    0xc(r1),r3
115
        l.movhi r3,hi(\name)
116
        l.ori   r3,r3,lo(\name)
117
        l.jr    r3
118
        l.nop
119
 
120
        .endm
121
 
122
        .macro unhandled_exception
123
        l.ori r3, r0, 1
124
        l.j 0
125
        l.nop NOP_EXIT
126
 
127
        .endm
128
 
129
/* Utility macro: store the cpu context on the stack */
130
        .macro store_context
131
        l.sw    0x8(r1),r2
132
        l.sw    0x10(r1),r4
133
        l.sw    0x14(r1),r5
134
        l.sw    0x18(r1),r6
135
        l.sw    0x1c(r1),r7
136
        l.sw    0x20(r1),r8
137
        l.sw    0x24(r1),r9
138
        l.sw    0x28(r1),r10
139
        l.sw    0x2c(r1),r11
140
        l.sw    0x30(r1),r12
141
        l.sw    0x34(r1),r13
142
        l.sw    0x38(r1),r14
143
        l.sw    0x3c(r1),r15
144
        l.sw    0x40(r1),r16
145
        l.sw    0x44(r1),r17
146
        l.sw    0x48(r1),r18
147
        l.sw    0x4c(r1),r19
148
        l.sw    0x50(r1),r20
149
        l.sw    0x54(r1),r21
150
        l.sw    0x58(r1),r22
151
        l.sw    0x5c(r1),r23
152
        l.sw    0x60(r1),r24
153
        l.sw    0x64(r1),r25
154
        l.sw    0x68(r1),r26
155
        l.sw    0x6c(r1),r27
156
        l.sw    0x70(r1),r28
157
        l.sw    0x74(r1),r29
158
        l.sw    0x78(r1),r30
159
        l.sw    0x7c(r1),r31
160
        .endm
161
 
162
/* Utility macro: restore the cpu context from the stack */
163
        .macro restore_context
164
        l.lwz   r2,0x8(r1)
165
        l.lwz   r3,0xc(r1)
166
        l.lwz   r4,0x10(r1)
167
        l.lwz   r5,0x14(r1)
168
        l.lwz   r6,0x18(r1)
169
        l.lwz   r7,0x1c(r1)
170
        l.lwz   r8,0x20(r1)
171
        l.lwz   r9,0x24(r1)
172
        l.lwz   r10,0x28(r1)
173
        l.lwz   r11,0x2c(r1)
174
        l.lwz   r12,0x30(r1)
175
        l.lwz   r13,0x34(r1)
176
        l.lwz   r14,0x38(r1)
177
        l.lwz   r15,0x3c(r1)
178
        l.lwz   r16,0x40(r1)
179
        l.lwz   r17,0x44(r1)
180
        l.lwz   r18,0x48(r1)
181
        l.lwz   r19,0x4c(r1)
182
        l.lwz   r20,0x50(r1)
183
        l.lwz   r21,0x54(r1)
184
        l.lwz   r22,0x58(r1)
185
        l.lwz   r23,0x5c(r1)
186
        l.lwz   r24,0x60(r1)
187
        l.lwz   r25,0x64(r1)
188
        l.lwz   r26,0x68(r1)
189
        l.lwz   r27,0x6c(r1)
190
        l.lwz   r28,0x70(r1)
191
        l.lwz   r29,0x74(r1)
192
        l.lwz   r30,0x78(r1)
193
        l.lwz   r31,0x7c(r1)
194
        .endm
195
 
196
/* actual code */
197
 
198
        .section .stack, "aw", @nobits
199
 
200
.space  STACK_SIZE
201
_stack:
202
 
203
/* Exception vectors */
204
 
205
        .section .vectors, "ax"
206
 
207
        .org 0x100
208
_reset:
209
        l.movhi r0,0
210
        l.addi  r3,r0,SPR_SR_SM
211
        l.mtspr r0,r3,SPR_SR
212
        load32i r3,_start
213
        l.jr    r3
214
        l.nop
215
 
216
        .org 0x200
217
        unhandled_exception
218
 
219
        .org 0x300
220
        unhandled_exception
221
 
222
        .org 0x400
223
        unhandled_exception
224
 
225
        .org 0x500
226
        exception_vector OSTickISR
227
 
228
        .org 0x600
229
        exception_vector _align
230
 
231
        .org 0x700
232
        unhandled_exception
233
 
234
        .org 0x800
235
        exception_vector UserISR
236
 
237
        .org 0x900
238
        unhandled_exception
239
 
240
        .org 0xa00
241
        unhandled_exception
242
 
243
        .org 0xb00
244
        unhandled_exception
245
 
246
        .org 0xc00
247
        exception_vector OSCtxSw
248
 
249
 
250
        /* Start of text section */
251
 
252
        .section .text
253
 
254
        /* _start function - called immediately after reset */
255
_start:
256
 
257
        /* Instruction cache enable */
258
        /* Check if IC present and skip enabling otherwise */
259
        l.mfspr r24,r0,SPR_UPR
260
        l.andi  r26,r24,SPR_UPR_ICP
261
        l.sfeq  r26,r0
262
        l.bf    .L8
263
        l.nop
264
 
265
        /* Disable IC */
266
        l.mfspr r6,r0,SPR_SR
267
        l.addi  r5,r0,-1
268
        l.xori  r5,r5,SPR_SR_ICE
269
        l.and   r5,r6,r5
270
        l.mtspr r0,r5,SPR_SR
271
 
272
        /* Establish cache block size
273
        If BS=0, 16;
274
        If BS=1, 32;
275
        r14 contain block size
276
        */
277
        l.mfspr r24,r0,SPR_ICCFGR
278
        l.andi  r26,r24,SPR_ICCFGR_CBS
279
        l.srli  r28,r26,7
280
        l.ori   r30,r0,16
281
        l.sll   r14,r30,r28
282
 
283
        /* Establish number of cache sets
284
        r16 contains number of cache sets
285
        r28 contains log(# of cache sets)
286
        */
287
        l.andi  r26,r24,SPR_ICCFGR_NCS
288
        l.srli  r28,r26,3
289
        l.ori   r30,r0,1
290
        l.sll   r16,r30,r28
291
 
292
        /* Invalidate IC */
293
        l.addi  r6,r0,0
294
        l.sll   r5,r14,r28
295
 
296
.L7:
297
        l.mtspr r0,r6,SPR_ICBIR
298
        l.sfne  r6,r5
299
        l.bf    .L7
300
        l.add   r6,r6,r14
301
 
302
        /* Enable IC */
303
        l.mfspr r6,r0,SPR_SR
304
        l.ori   r6,r6,SPR_SR_ICE
305
        l.mtspr r0,r6,SPR_SR
306
        l.nop
307
        l.nop
308
        l.nop
309
        l.nop
310
        l.nop
311
        l.nop
312
        l.nop
313
        l.nop
314
 
315
.L8:
316
        /* Data cache enable */
317
        /* Check if DC present and skip enabling otherwise */
318
        l.mfspr r24,r0,SPR_UPR
319
        l.andi  r26,r24,SPR_UPR_DCP
320
        l.sfeq  r26,r0
321
        l.bf    .L10
322
        l.nop
323
        /* Disable DC */
324
        l.mfspr r6,r0,SPR_SR
325
        l.addi  r5,r0,-1
326
        l.xori  r5,r5,SPR_SR_DCE
327
        l.and   r5,r6,r5
328
        l.mtspr r0,r5,SPR_SR
329
        /* Establish cache block size
330
           If BS=0, 16;
331
           If BS=1, 32;
332
           r14 contain block size
333
        */
334
        l.mfspr r24,r0,SPR_DCCFGR
335
        l.andi  r26,r24,SPR_DCCFGR_CBS
336
        l.srli  r28,r26,7
337
        l.ori   r30,r0,16
338
        l.sll   r14,r30,r28
339
        /* Establish number of cache sets
340
           r16 contains number of cache sets
341
           r28 contains log(# of cache sets)
342
        */
343
        l.andi  r26,r24,SPR_DCCFGR_NCS
344
        l.srli  r28,r26,3
345
        l.ori   r30,r0,1
346
        l.sll   r16,r30,r28
347
        /* Invalidate DC */
348
        l.addi  r6,r0,0
349
        l.sll   r5,r14,r28
350
.L9:
351
        l.mtspr r0,r6,SPR_DCBIR
352
        l.sfne  r6,r5
353
        l.bf    .L9
354
        l.add   r6,r6,r14
355
        /* Enable DC */
356
        l.mfspr r6,r0,SPR_SR
357
        l.ori   r6,r6,SPR_SR_DCE
358
        l.mtspr r0,r6,SPR_SR
359
 
360
.L10:
361
 
362
        /* Clear BSS */
363
        load32i r28, ___bss_start
364
        load32i r30, __end
365
1:
366
        l.sw    (0)(r28), r0
367
        l.sfltu r28, r30
368
        l.bf    1b
369
        l.addi  r28, r28, 4
370
 
371
        /* Initialise stack pointer */
372
        load32i r1,_stack-4
373
 
374
        l.addi  r2,r0,-3
375
        l.and   r1,r1,r2
376
        l.ori   r2,r1,0
377
 
378
        load32i r3,main
379
 
380
        l.jr    r3
381
        l.addi  r3,r0,0
382
 
383
 
384
 
385
_align:
386
        l.ori   r3,r0,0x600
387
        l.nop   NOP_REPORT
388
        l.mfspr r3,r0,SPR_EPCR_BASE
389
        l.nop   NOP_REPORT
390
        l.lwz   r3,0(r3)
391
        l.nop   NOP_REPORT
392
        l.mfspr r3,r0,SPR_EEAR_BASE
393
        l.nop   NOP_REPORT
394
        /* Loop in place, cause simulator to exit */
395
        l.ori   r3,r0,1
396
        l.j     0
397
        l.nop   NOP_EXIT
398
 
399
/*
400
------------------------------
401
            OSCtxSw
402
------------------------------
403
 Description :
404
 This routine switches between two different tasks.
405
 The task state of one is saved on its kernel stack.
406
 Then the state of the other is restored from its kernel stack.
407
 
408
 There maybe memory management hardware issues
409
 
410
 Finally, we can return to the second task, via the 'return'.
411
 
412
 Includes OSIntCtxSw
413
------------------------------
414
 Uses:
415
------------------------------
416
*/
417
 
418
OSCtxSw:
419
        /* l.sys exception for now so we are in supervisor mode */
420
        /* exception  - recover pc from epcr */
421
 
422 526 julius
        l.mfspr r3,r0,SPR_EPCR_BASE     /* save program counter that was put in
423
                                                exception register */
424 471 julius
        l.sw    0(r1),r3
425 526 julius
        l.mfspr r3,r0,SPR_ESR_BASE      /* save status register that was put in
426
                                                exception register */
427 471 julius
        l.sw    4(r1),r3
428
 
429
        store_context
430
                                        /* Store current stack pointer   */
431
        load32i r3,OSTCBCur            /* r3= &OSTCBCur */
432
 
433
        l.lwz   r3,0(r3)                /* r3 = &CurrentTask.OSTCBStkPtr  */
434
        l.sw    0(r3),r1                /* CurrentTask.OSTCBStkPtr = SP */
435
 
436
OSIntCtxSw:
437
        l.jal   OSTaskSwHook           /* call OSTaskSwHook */
438
        l.nop
439
 
440
        load32i r2,OSTCBHighRdy        /* r2= &OSTCBHighRdy */
441
        l.lwz   r2,0(r2)
442
        load32i r3,OSTCBCur            /* r3= &OSTCBCur */
443
        l.sw    0(r3),r2                /* OSTCBCur = OSTCBHighRdy */
444
 
445
        load32i r3,OSPrioHighRdy       /* r3= &OSPrioHighRdy */
446
        l.lbz   r3, 0(r3)
447
        load32i r4,OSPrioCur           /* r4= &OSPrioCur */
448
        l.sb    0(r4), r3               /* OSPrioCur = OSPrioHighRdy */
449
 
450
        l.lwz   r1, 0(r2)               /* sp = OSTCBHighRdy */
451
 
452
 
453
        l.lwz   r2,0(r1)                /* load context for task to be resumed */
454
        l.mtspr r0,r2,SPR_EPCR_BASE
455
        l.lwz   r2,4(r1)
456
        l.mtspr r0,r2,SPR_ESR_BASE
457
 
458
        restore_context
459
 
460
OSCtxSwBP:
461
        l.addi  r1,r1,STK_FRAME_SIZE
462
        l.rfe
463
        l.nop
464
 
465
/*
466
------------------------------
467
        OSStartHighRdy
468
------------------------------
469
 Description :
470
   Starts the highest priority task that is available to run
471
 
472
 OSStartHighRdy() MUST:
473
  a) Call OSTaskSwHook() then,
474
  b) Set OSRunning to TRUE,
475
  c) Switch to the HPT
476
 
477
------------------------------
478
 Uses :
479
------------------------------
480
*/
481
OSStartHighRdy:
482
 
483 526 julius
        l.jal   OSTaskSwHook            /* call OSTaskSwHook */
484 471 julius
        l.nop
485
 
486 526 julius
        load32i r3,OSRunning            /* r3= &OSRunning */
487 471 julius
 
488
        l.ori   r4,r0, 0x01             /* set OSRunning == TRUE */
489
        l.sb    0(r3), r4
490 526 julius
                                        /* load stack pointer from next task's
491
                                           TCB area  */
492
        load32i r3,OSTCBHighRdy         /* r3 = &OSTCBHighRdy */
493 471 julius
        l.lwz   r3,0(r3)                /* r3 = &OS_TCB */
494
        l.lwz   r1, 0(r3)               /* stack is the first element */
495
 
496
        l.lwz   r2,0(r1)
497
        l.mtspr r0,r2,SPR_EPCR_BASE
498
        l.lwz   r2,4(r1)
499
        l.mtspr r0,r2,SPR_ESR_BASE
500
 
501
        restore_context
502
 
503
        l.addi  r1,r1,STK_FRAME_SIZE
504
        l.rfe
505
        l.nop
506
 
507
/*
508
------------------------------
509
        OSTickISR
510
------------------------------
511
 Description :
512
 
513
------------------------------
514
 Uses :
515
------------------------------
516
*/
517
OSTickISR:
518 526 julius
        l.mfspr r3,r0,SPR_EPCR_BASE     /* save program counter that was put
519
                                           in exception register */
520 471 julius
        l.sw    0(r1),r3
521 526 julius
        l.mfspr r3,r0,SPR_ESR_BASE      /* save status register that was put in
522
                                           exception register */
523 471 julius
        l.sw    4(r1),r3
524
 
525
        store_context
526
/* either call OSIntEnter or Increment OSIntNesting */
527
 
528
/*
529
        l.jal   OSIntEnter
530
        l.nop
531
        load32i r2,OSIntNesting
532
        l.lbz   r3,0(r2)
533
*/
534
        load32i r2,OSIntNesting     /* r2 &OSIntNesting */
535
        l.lbz   r3,0(r2)             /* r3 OSIntNesting  */
536
        l.addi  r3,r3,1
537
        l.sb    0(r2),r3
538
 
539
   /* if (OSIntNesting == 1) OSTCBCur->OSTCBStkPtr = sp */
540
        l.sfeqi r3,1
541
        l.bnf   nest_not_one
542
        l.nop
543
 
544
        load32i r4,OSTCBCur            /* set pointer to Current TCB pointer */
545
                                        /* r4= &OSTCBCur */
546
 
547
                                        /* Store current stack pointer   */
548
        l.lwz   r5,0(r4)                /* r5 = &CurrentTask.OSTCBStkPtr  */
549
        l.sw    0(r5),r1                /* CurrentTask.OSTCBStkPtr = SP */
550
 
551
nest_not_one:
552
        /* clear interrupt */
553
        load32i r3,SPR_TTMR_LOAD
554
        l.mtspr r0,r3,SPR_TTMR
555
 
556
        /* optionally re enable interrupt */
557
 
558
        /*Call OSTimeTick()*/
559
        l.jal   OSTimeTick
560
        l.nop
561
        /*Call OSIntExit()*/
562
        l.jal   OSIntExit
563
        l.nop
564 526 julius
                                        /* load stack pointer from next task's
565
                                           TCB area  */
566
        load32i r3,OSTCBHighRdy         /* r3 = &OSTCBHighRdy */
567 471 julius
        l.lwz   r3,0(r3)                /* r3 = &OS_TCB */
568
        l.lwz   r1, 0(r3)               /* stack is the first element */
569
 
570
        l.lwz   r2,0(r1)
571
        l.mtspr r0,r2,SPR_EPCR_BASE
572
        l.lwz   r2,4(r1)
573
        l.mtspr r0,r2,SPR_ESR_BASE
574
 
575
        restore_context
576
 
577
        l.addi  r1,r1,STK_FRAME_SIZE
578
        l.rfe
579
        l.nop
580
 
581
 
582
        /*
583
------------------------------
584
        UserISR
585
------------------------------
586
 Description :
587
 
588
------------------------------
589
 Uses :
590
------------------------------
591
*/
592
UserISR:
593 526 julius
        l.mfspr r3,r0,SPR_EPCR_BASE     /* save program counter that was put in
594
                                                exception register */
595
        l.sw    0(r1),r3
596
        l.mfspr r3,r0,SPR_ESR_BASE      /* save status register that was put
597
                                                in exception register */
598
        l.sw    4(r1),r3
599 471 julius
 
600
        store_context
601
/* either call OSIntEnter or Increment OSIntNesting */
602
 
603
/*
604
        l.jal   _OSIntEnter
605
        l.nop
606
        load32i r2,_OSIntNesting
607
        l.lbz   r3,0(r2)
608
*/
609
        load32i r2,OSIntNesting     /* r2 &OSIntNesting */
610
 
611
        l.lbz   r3,0(r2)             /* r3 OSIntNesting  */
612
        l.addi  r3,r3,1
613
        l.sb    0(r2),r3
614
 
615
   /* if (OSIntNesting == 1) OSTCBCur->OSTCBStkPtr = sp */
616
        l.sfeqi r3,1
617
        l.bnf   Unest_not_one
618
        l.nop
619
 
620
        load32i r4,OSTCBCur            /* set pointer to Current TCB pointer */
621
                                        /* r4= &OSTCBCur */
622
 
623
                                        /* Store current stack pointer   */
624
        l.lwz   r5,0(r4)                /* r5 = &CurrentTask.OSTCBStkPtr  */
625
        l.sw    0(r5),r1                /* CurrentTask.OSTCBStkPtr = SP */
626
 
627
Unest_not_one:
628
        /* clear interrupt */
629
        l.mtspr r0,r0,SPR_PICSR
630
 
631
        /* optionally re enable interrupt */
632
 
633
        /*Call interrupt service routine */
634
 
635
        /*Call OSIntExit()*/
636
        l.jal   OSIntExit
637
        l.nop
638
 
639
                                        /* load stack pointer from next task's TCB area  */
640
        load32i r3,OSTCBHighRdy        /* r3 = &OSTCBHighRdy */
641
        l.lwz   r3,0(r3)                /* r3 = &OS_TCB */
642
        l.lwz   r1, 0(r3)               /* stack is the first element */
643
 
644
        l.lwz   r2,0(r1)
645
        l.mtspr r0,r2,SPR_EPCR_BASE
646
        l.lwz   r2,4(r1)
647
        l.mtspr r0,r2,SPR_ESR_BASE
648
 
649
        restore_context
650
 
651
        l.addi  r1,r1,STK_FRAME_SIZE
652
        l.rfe
653
        l.nop

powered by: WebSVN 2.1.0

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