1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "../port/error.h"
- #include "msaturn.h"
- enum {
- Timer_ctrl = Saturn + 0x0106,
- Timer0_load = Saturn + 0x0200,
- Timer0_cnt = Saturn + 0x0204,
- Timer1_load = Saturn + 0x0300,
- Timer1_cnt = Saturn + 0x0304,
-
- T0_event = RBIT(13, ushort),
- T0_ie = RBIT(14, ushort),
- T0_cen = RBIT(15, ushort),
- T1_event = RBIT(5, ushort),
- T1_ie = RBIT(6, ushort),
- T1_cen = RBIT(7, ushort),
- };
- static ulong ticks;
- static Lock tlock;
- static ushort timer_ctl;
- void
- saturntimerintr(Ureg *u, void*)
- {
- ushort ctl = *(ushort*)Timer_ctrl, v = 0;
- if(ctl&T1_event){
- v = T1_event;
- ticks++;
- }
-
- *(ushort*)Timer_ctrl = timer_ctl|T0_event|v;
- intack();
- timerintr(u, 0);
- }
- void
- timerinit(void)
- {
- *(ushort*)Timer_ctrl = 0;
- *(ulong*)Timer0_load = m->bushz / HZ;
- *(ulong*)Timer0_cnt = m->bushz / HZ;
- *(ulong*)Timer1_load = m->bushz;
- *(ulong*)Timer1_cnt = m->bushz;
- intrenable(Vectimer0, saturntimerintr, nil, "timer");
- timer_ctl = T0_cen|T0_ie|T1_cen;
- *(ushort*)Timer_ctrl = timer_ctl;
- }
- uvlong
- fastticks(uvlong *hz)
- {
- assert(*(ushort*)Timer_ctrl&T1_cen);
- if(*(ushort*)Timer_ctrl&T1_event){
- *(ushort*)Timer_ctrl = timer_ctl|T1_event;
- ticks++;
- }
-
- if (hz)
- *hz = m->bushz;
- return (uvlong)ticks*m->bushz+(uvlong)(m->bushz-*(ulong*)Timer1_cnt);
- }
- void
- timerset(uvlong next)
- {
- ulong offset;
- uvlong now;
- ilock(&tlock);
- *(ushort*)Timer_ctrl = T1_cen;
- now = fastticks(nil);
- offset = next - now;
- if((long)offset < 10000)
- offset = 10000;
- else if(offset > m->bushz)
- offset = m->bushz;
- *(ulong*)Timer0_cnt = offset;
- *(ushort*)Timer_ctrl = timer_ctl;
- assert(*(ushort*)Timer_ctrl & T1_cen);
- iunlock(&tlock);
- }
|