Kernel[Tegra2] - Messing about debugging tegra stuff
authorJohn Hodge <[email protected]>
Mon, 28 Jan 2013 04:14:20 +0000 (12:14 +0800)
committerJohn Hodge <[email protected]>
Mon, 28 Jan 2013 04:14:20 +0000 (12:14 +0800)
KernelLand/Kernel/arch/armv7/main.c
KernelLand/Kernel/arch/armv7/platform_tegra2.c
KernelLand/Kernel/arch/armv7/platform_tegra2.h
KernelLand/Kernel/arch/armv7/start.S
KernelLand/Kernel/arch/armv7/vpci_tegra2.c
KernelLand/Kernel/include/vfs_ext.h
KernelLand/Modules/Display/Tegra2Vid/main.c
KernelLand/Modules/USB/EHCI/ehci.c
KernelLand/Modules/armv7/GIC/gic.c

index d05c01e..903f5fc 100644 (file)
@@ -40,12 +40,15 @@ int kmain(void)
        VFS_Init();
 
        // Boot modules?
+       // - most ARMv7 configs use a GIC
        Module_EnsureLoaded("armv7_GIC");
+       
+       Time_Setup();
 
        //
        LogF("Moving to arch-independent init\n");
        #if PLATFORM_is_tegra2
-       System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid -USB_EHCI:C5000000-14,C5004000-15");
+       System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid");
        #else
        System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=PL110");
        #endif
index 36dbb56..0ec90f3 100644 (file)
@@ -29,7 +29,8 @@ void  Time_Setup(void);
 tPAddr gGIC_InterfaceAddr = 0x50040000;
 tPAddr gGIC_DistributorAddr = 0x50041000;
 // - Map of timer registers
-struct sTimersMap *gpTimersMap;
+volatile struct sTimersMap *gpTimersMap;
+volatile struct sClockResetMap *gpClockResetMap;
 // - Interrupt controller code commented out, because the Tegra2 also has a GIC
 #if 0
 struct sIRQMap gpIRQMap;
@@ -41,15 +42,40 @@ struct sIRQMap      gpIRQMap;
 void Timer_IRQHandler_SysClock(int IRQ, void *_unused)
 {
        giTimestamp += 100;
-       gpTimersMap->TMR0.PCR_0 = (1<<31);
+       gpTimersMap->TMR1.PCR_0 = (1<<30);
 }
 
 void Time_Setup(void)
 {
        gpTimersMap = (void*)MM_MapHWPages(0x60005000, 1);
+       gpClockResetMap = (void*)MM_MapHWPages(0x60006000, 1);
        // Timer 1 (used for system timekeeping)
        IRQ_AddHandler(0*32+0, Timer_IRQHandler_SysClock, NULL);
-       gpTimersMap->TMR0.PTV_0 = (1<31)|(1<30)|(100*1000);     // enable, periodic, 100 ms
+       gpTimersMap->TMR1.PTV_0 = (1<<31)|(1<<30)|(100*1000-1); // enable, periodic, 100 ms
+       gpTimersMap->TMR1.PCR_0 = (1<<30);
+       Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
+
+       // Disabled until IRQs work
+       //gpClockResetMap->RST_Source = (1 << 5)|(0<<4)|(7);    // Full reset on watchdog timeout
+
+       Log_Debug("Tegra2Tme", "TIMERUS_USEC_CFG = 0x%x", gpTimersMap->TIMERUS.USEC_CFG);
+       Log_Debug("Tegra2Tme", "TIMERUS_CNTR_1US = 0x%x", gpTimersMap->TIMERUS.CNTR_1US);
+       Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
+       Log_Debug("Tegra2Tme", "TMR0.PTV = 0x%x", gpTimersMap->TMR1.PTV_0);
+       for( int i = 0; i < 5; i ++ ) {
+               for( int j = 0; j < 1000*1000; j ++ )
+               {
+                       __asm__ __volatile__ ("mov r0, r0");
+                       __asm__ __volatile__ ("mov r0, r0");
+                       __asm__ __volatile__ ("mov r0, r0");
+               }
+               Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
+       }
+       Log_Debug("Tegra2Tme", "TMR0.PCR = 0x%x", gpTimersMap->TMR1.PCR_0);
+       Log_Debug("Tegra2Tme", "GICC_HPPIR = 0x%x", *(Uint32*)(0xF0000000 + 0x18));
+       Log_Debug("Tegra2Tme", "GICC_IAR = 0x%x", *(Uint32*)(0xF0000000 + 0xC));
+       Log_Debug("Tegra2Tme", "GICD_ISPENDR0 = 0x%x", *(Uint32*)(0xF0001000 + 0x200 + 0*4));
+       Log_Debug("Tegra2Tme", "GICD_ISPENDR1 = 0x%x", *(Uint32*)(0xF0001000 + 0x200 + 1*4));
 }
 
 #if 0
index 67f7582..2af310e 100644 (file)
@@ -13,15 +13,29 @@ struct sTimerRegs
        Uint32  PTV_0;  // Control / Target value
        Uint32  PCR_0;  // Current value / IRQ clear
 };
+struct sTimerUSRegs
+{
+       Uint32  CNTR_1US;       // 16:16 microsecond counter
+       Uint32  USEC_CFG;       // 8:8 num/den (n+1)/(den+1) us per clock
+       Uint32  _padding[0x3c-0x8];
+       Uint32  CNTR_Freeze;    // Freeze timers when in debug?
+};
 struct sTimersMap
 {
-       struct sTimerRegs       TMR0;
        struct sTimerRegs       TMR1;
-       // TMRUS
-       char _padding[ 0x50-0x10 ];
-
        struct sTimerRegs       TMR2;
+
+       struct sTimerUSRegs     TIMERUS;
+
        struct sTimerRegs       TMR3;
+       struct sTimerRegs       TMR4;
+};
+
+struct sClockResetMap
+{
+       Uint32  RST_Source;
+       Uint32  RST_Devices;
+       // ...
 };
 
 #if 0
index 71534f5..8193b31 100644 (file)
@@ -67,13 +67,17 @@ _start:
        @
        mrc p15, 0, r0, c0, c1, 1
        and r0, #0xF0
+       beq .no_sec_ext
        @ - Present
-       ldrne r0,=KERNEL_BASE
-       mcrne p15, 0, r0, c12, c0, 0    @ Set the VBAR (brings exceptions into high memory)
+       ldr r0,=KERNEL_BASE
+       mcr p15, 0, r0, c12, c0, 0      @ Set the VBAR (brings exceptions into high memory)
+       b .exceptions_vectored
+.no_sec_ext:
        @ - Absent
-       mrceq p15, 0, r0, c1, c0, 0     @ Set SCTLR.V
-       orreq r0, #0x2000
-       mcreq p15, 0, r0, c1, c0, 0
+       mrc p15, 0, r0, c1, c0, 0       @ Set SCTLR.V
+       orr r0, #0x2000
+       mcr p15, 0, r0, c1, c0, 0
+.exceptions_vectored:
 
        mov r1, #'-'
        str r1, [r2]    
index 1d01fb0..9c05006 100644 (file)
 
 // === GLOBALS ===
 tVPCI_Device   gaVPCI_Devices[] = {
-       // NOTE: USB Controllers moved to command line arguments
        #if 0
        {
        .Vendor=0x0ACE,.Device=0x1100,
-       .Class = 0x0C032100,    // Serial, USB, ECHI
+       .Class = 0x0C032000,    // Serial, USB, ECHI
        .BARs = {0xC5000000,0,0,0,0,0},
        .IRQ = 0*32+20,
        },
index a130ac6..1bc3e18 100644 (file)
@@ -118,11 +118,11 @@ typedef struct sVFS_ACL
        struct {
                unsigned Group: 1;      //!< Group (as opposed to user) flag
                unsigned ID:    31;     //!< ID of Group/User (-1 for nobody/world)
-       };
+       } Ent;
        struct {
                unsigned Inv:   1;      //!< Invert Permissions
                unsigned Perms: 31;     //!< Permission Flags
-       };
+       } Perm;
 } tVFS_ACL;
 
 /**
index 34b58f1..09bbbb8 100644 (file)
@@ -98,7 +98,7 @@ int Tegra2Vid_Install(char **Arguments)
        gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 256/4);
 
        #if DUMP_REGISTERS
-       Tegra2Vid_int_DumpRegisters();
+//     Tegra2Vid_int_DumpRegisters();
        #endif
 
        // HACK!!!
@@ -148,6 +148,7 @@ int Tegra2Vid_Install(char **Arguments)
 #endif
 
        gpTegra2Vid_Cursor = (void*)MM_AllocDMA(1, 26, NULL);
+       Log_Debug("Tegra2Vid", "gpTegra2Vid_Cursor = %p", gpTegra2Vid_Cursor);
 
        Tegra2Vid_int_SetMode(0);
 
index a2acca2..c970eb4 100644 (file)
@@ -79,11 +79,16 @@ int EHCI_Initialise(char **Arguments)
        {
                Uint32  addr = PCI_GetBAR(id, 0);
                if( addr == 0 ) {
-                       // Oops, PCI BIOS emulation time
+                       // TODO: PCI BIOS emulation time
                }
+               if( addr & 1 ) {
+                       // TODO: Error
+                       continue ;
+               }
+               addr &= ~0xF;
                Uint8   irq = PCI_GetIRQ(id);
                if( irq == 0 ) {
-                       // TODO: The same
+                       // TODO: Error?
                }
 
                Log_Log("ECHI", "Controller at PCI %i 0x%x IRQ 0x%x",
@@ -96,7 +101,7 @@ int EHCI_Initialise(char **Arguments)
                }
        }
 
-       for( int i = 0; Arguments[i]; i ++ )
+       for( int i = 0; Arguments && Arguments[i]; i ++ )
        {
                char *pos = Arguments[i], *next;
                LOG("pos = '%s'", pos);
@@ -153,7 +158,7 @@ int EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum)
        cont->TDPool = NULL;
 
        // -- Build up structure --
-       cont->CapRegs = (void*)MM_MapHWPages(BaseAddress, 1);
+       cont->CapRegs = (void*)( MM_MapHWPages(BaseAddress, 1) + (BaseAddress % PAGE_SIZE) );
        if( !cont->CapRegs ) {
                Log_Warning("EHCI", "Can't map 1 page at %P into kernel space", BaseAddress);
                goto _error;
@@ -164,6 +169,12 @@ int EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum)
                        BaseAddress, cont->CapRegs->CapLength);
                goto _error;
        }
+       if( BaseAddress % PAGE_SIZE + cont->CapRegs->CapLength + sizeof(tEHCI_CapRegs) > PAGE_SIZE ) {
+               Log_Warning("EHCI", "%P: Cap regs over page boundary (+0x%x bytes)",
+                        BaseAddress % PAGE_SIZE + cont->CapRegs->CapLength + sizeof(tEHCI_CapRegs)
+                        );
+               goto _error;
+       }
        cont->OpRegs = (void*)( (Uint32*)cont->CapRegs + cont->CapRegs->CapLength / 4 );
        // - Allocate periodic queue
        tPAddr  unused;
index 6544179..a918f68 100644 (file)
@@ -28,8 +28,8 @@ void  GIC_IRQHandler(void);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, 0x100, armv7_GIC, GIC_Install, NULL, NULL);
-Uint32 *gpGIC_DistributorBase;
-Uint32 *gpGIC_InterfaceBase;
+volatile Uint32        *gpGIC_DistributorBase;
+volatile Uint32        *gpGIC_InterfaceBase;
 tIRQ_Handler   gaIRQ_Handlers[N_IRQS];
 void   *gaIRQ_HandlerData[N_IRQS];
 
@@ -37,12 +37,17 @@ void        *gaIRQ_HandlerData[N_IRQS];
 int GIC_Install(char **Arguments)
 {
        // Initialise
+       Log_Debug("GIC", "Dist: %P, Interface: %P",
+               gGIC_DistributorAddr, gGIC_InterfaceAddr);
        gpGIC_InterfaceBase = (void*)MM_MapHWPages(gGIC_InterfaceAddr, 1);
        LOG("gpGIC_InterfaceBase = %p", gpGIC_InterfaceBase);
        gpGIC_DistributorBase = (void*)MM_MapHWPages(gGIC_DistributorAddr, 1);
        LOG("gpGIC_DistributorBase = %p", gpGIC_DistributorBase);
 
-       gpGIC_InterfaceBase[GICC_PMR] = 0xFF;   
+       gpGIC_InterfaceBase[GICC_CTLR] = 0;     // Disable CPU interaface
+       LOG("GICC_IAR = %x (CTLR=0)", gpGIC_InterfaceBase[GICC_IAR]);
+
+       gpGIC_InterfaceBase[GICC_PMR] = 0xFF;   // Effectively disable prioritories
        gpGIC_InterfaceBase[GICC_CTLR] = 1;     // Enable CPU
        gpGIC_DistributorBase[GICD_CTLR] = 1;   // Enable Distributor
 
@@ -50,13 +55,32 @@ int GIC_Install(char **Arguments)
 
        __asm__ __volatile__ ("cpsie if");      // Enable IRQs and FIQs
 
+#if 0
+       for( int i = 0; i < N_IRQS/32; i ++ ) {
+               Log_Debug("GIC", "GICD_ISENABLER%i %x = %08x",
+                       i, GICD_ISENABLER0 + i,
+                       gpGIC_DistributorBase[GICD_ISENABLER0+i]);
+               gpGIC_DistributorBase[GICD_ISENABLER0+i] = 0;
+       }
+#endif
+
+       #if 0
+       // Testing - First 32 actual interrupts enabled
+       gpGIC_DistributorBase[GICD_ISENABLER0+1] = 0xFFFFFFFF;
+       for( int i = 0; i < 32/4; i ++ )
+               gpGIC_DistributorBase[GICD_ITARGETSR0+8+i] = 0x01010101;
+       #endif
+
+       // Clear out pending IRQs.
+       gpGIC_InterfaceBase[GICC_EOIR] = gpGIC_InterfaceBase[GICC_IAR];
+
        return MODULE_ERR_OK;
 }
 
 void GIC_IRQHandler(void)
 {
        Uint32  num = gpGIC_InterfaceBase[GICC_IAR];
-//     Log_Debug("GIC", "IRQ 0x%x", num);
+       Log_Debug("GIC", "IRQ 0x%x", num);
        gaIRQ_Handlers[num]( num, gaIRQ_HandlerData[num] );
        gpGIC_InterfaceBase[GICC_EOIR] = num;
 }
@@ -67,21 +91,26 @@ int IRQ_AddHandler(int IRQ, tIRQ_Handler Handler, void *Ptr)
                return 1;
        }
        
-       LOG("IRQ = %i", IRQ);
        IRQ += 32;      // 32 internal IRQs
-       LOG("IRQ = %i (after adjust)", IRQ);
-       LOG("mask = 0x%x", 1 << (IRQ & (31-1)));
+       // - Enable IRQ, clear pending and send to CPU 1 only
        gpGIC_DistributorBase[GICD_ISENABLER0+IRQ/32] = 1 << (IRQ & (32-1));
        ((Uint8*)&gpGIC_DistributorBase[GICD_ITARGETSR0])[IRQ] = 1;
+       gpGIC_DistributorBase[GICD_ICPENDR0+IRQ/32] = 1 << (IRQ & (32-1));
        
-//     Log_Warning("GIC", "TODO: Implement IRQ_AddHandler");
-       
-       if( gaIRQ_Handlers[IRQ] )
+       // TODO: Does the GIC need to handle IRQ sharing?
+       if( gaIRQ_Handlers[IRQ] ) {
+               Log_Warning("GIC", "IRQ %i already handled by %p, %p ignored",
+                       IRQ, gaIRQ_Handlers[IRQ], Handler);
                return 2;
+       }
        
        gaIRQ_Handlers[IRQ] = Handler;
        gaIRQ_HandlerData[IRQ] = Ptr;
        
+       Log_Debug("GIC", "IRQ %i handled by %p(%p)", IRQ, Handler, Ptr);
+
+       // DEBUG! Trip the interrupt    
+       gpGIC_DistributorBase[GICD_ISPENDR0+IRQ/32] = 1 << (IRQ & (32-1));
        return 0;
 }
 

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