Kernel/x86 - Added backtrace to running program in thread dump
[tpg/acess2.git] / KernelLand / Kernel / arch / armv7 / platform_tegra2.c
1 /*
2  * Acess2 Kernel ARMv7 Port
3  * - By John Hodge (thePowersGang)
4  *
5  * platform_tegra2.c
6  * - Tegra2 Core code
7  */
8 #include <acess.h>
9 #include "platform_tegra2.h"
10
11 // === CONSTANTS ===
12 #define TIMER0_INT      (0*32+0)        // Pri #0
13 #define TIMER1_INT      (0*32+1)        // Pri #1
14 #define TIMER2_INT      (1*32+9)        // Sec #9
15 #define TIMER3_INT      (1*32+10)       // Sec #10
16
17 // === Imports ===
18 extern volatile Sint64  giTimestamp;
19 extern volatile Uint64  giTicks;
20 extern volatile Uint64  giPartMiliseconds;
21 extern void     Timer_CallTimers(void);
22
23 // === PROTORTYPES ===
24 void    Timer_IRQHandler_SysClock(int IRQ, void *_unused);
25 void    Time_Setup(void);
26
27 // === GLOBALS ===
28 // - Addresses for the GIC to use
29 tPAddr  gGIC_InterfaceAddr = 0x50040000;
30 tPAddr  gGIC_DistributorAddr = 0x50041000;
31 // - Map of timer registers
32 volatile struct sTimersMap *gpTimersMap;
33 volatile struct sClockResetMap *gpClockResetMap;
34 // - Interrupt controller code commented out, because the Tegra2 also has a GIC
35 #if 0
36 struct sIRQMap  gpIRQMap;
37 #endif
38
39 // === CODE ===
40
41 // -- Timers --
42 void Timer_IRQHandler_SysClock(int IRQ, void *_unused)
43 {
44         giTimestamp += 100;
45         gpTimersMap->TMR1.PCR_0 = (1<<30);
46 }
47
48 void Timer_IRQHandler_Timer2(int IRQ, void *_unused)
49 {
50         Log_Debug("Tegra2Tme", "Timer 2");
51 }
52 void Timer_IRQHandler_Timer3(int IRQ, void *_unused)
53 {
54         Log_Debug("Tegra2Tme", "Timer 3");
55 }
56 void Timer_IRQHandler_Timer4(int IRQ, void *_unused)
57 {
58         Log_Debug("Tegra2Tme", "Timer 4");
59 }
60
61 void Time_MicroSleep(Uint16 Microsecs)
62 {
63         Uint32  cur_ts = gpTimersMap->TIMERUS.CNTR_1US;
64         Uint32  tgt_ts = cur_ts + Microsecs;
65         if( tgt_ts < cur_ts )
66                 while( gpTimersMap->TIMERUS.CNTR_1US > cur_ts )
67                         ;
68         while( gpTimersMap->TIMERUS.CNTR_1US < tgt_ts )
69                 ;
70 }
71
72 void Time_Setup(void)
73 {
74         gpTimersMap = (void*)MM_MapHWPages(0x60005000, 1);
75         gpClockResetMap = (void*)MM_MapHWPages(0x60006000, 1);
76         
77         // Timer 1 (used for system timekeeping)
78         IRQ_AddHandler(0*32+0, Timer_IRQHandler_SysClock, NULL);
79         IRQ_AddHandler(0*32+1, Timer_IRQHandler_Timer2, NULL);
80         IRQ_AddHandler(1*32+9, Timer_IRQHandler_Timer3, NULL);
81         IRQ_AddHandler(1*32+10, Timer_IRQHandler_Timer4, NULL);
82         gpTimersMap->TMR1.PTV_0 = (1<<31)|(1<<30)|(100*1000-1); // enable, periodic, 100 ms
83         gpTimersMap->TMR1.PCR_0 = (1<<30);
84         Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
85
86         // Disabled until IRQs work
87         //gpClockResetMap->RST_Source = (1 << 5)|(0<<4)|(7);    // Full reset on watchdog timeout
88
89         Log_Debug("Tegra2Tme", "TIMERUS_USEC_CFG = 0x%x", gpTimersMap->TIMERUS.USEC_CFG);
90         Log_Debug("Tegra2Tme", "TIMERUS_CNTR_1US = 0x%x", gpTimersMap->TIMERUS.CNTR_1US);
91         Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
92         Log_Debug("Tegra2Tme", "TMR0.PTV = 0x%x", gpTimersMap->TMR1.PTV_0);
93         for( int i = 0; i < 5; i ++ ) {
94                 for( int j = 0; j < 1000*1000; j ++ )
95                 {
96                         __asm__ __volatile__ ("mov r0, r0");
97                         __asm__ __volatile__ ("mov r0, r0");
98                         __asm__ __volatile__ ("mov r0, r0");
99                 }
100                 Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
101         }
102         Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
103         Log_Debug("Tegra2Tme", "GICC_HPPIR = 0x%x", *(Uint32*)(0xF0000000 + 0x18));
104         Log_Debug("Tegra2Tme", "GICC_IAR = 0x%x", *(Uint32*)(0xF0000000 + 0xC));
105         Log_Debug("Tegra2Tme", "GICD_ISPENDR0 = 0x%x", *(Uint32*)(0xF0001000 + 0x200 + 0*4));
106         Log_Debug("Tegra2Tme", "GICD_ISPENDR1 = 0x%x", *(Uint32*)(0xF0001000 + 0x200 + 1*4));
107 }
108
109 #if 0
110 // -- Interrupt Controller --
111 void IRQ_CtrlrHandler(struct sIRQRegs *Ctrlr, int Ofs)
112 {
113         // Primary CPU only?
114         // TODO: 
115 }
116
117 void IRQ_RootHandler(void)
118 {
119         IRQ_CtrlrHandler(&gpIRQMap->Pri, 0*32);
120         IRQ_CtrlrHandler(&gpIRQMap->Sec, 1*32);
121         IRQ_CtrlrHandler(&gpIRQMap->Tri, 2*32);
122         IRQ_CtrlrHandler(&gpIRQMap->Quad, 3*32);
123 }
124
125 void IRQ_Setup(void)
126 {
127         gpIRQMap = (void*)MM_MapHWPages(0x60004000, 1);
128         
129         gpIRQHandler = IRQ_RootHandler;
130 }
131 #endif

UCC git Repository :: git.ucc.asn.au