From 52ee5f26d93bc5465c0ba670faf1f87382bae1fa Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 28 Jan 2013 12:14:20 +0800 Subject: [PATCH] Kernel[Tegra2] - Messing about debugging tegra stuff --- KernelLand/Kernel/arch/armv7/main.c | 5 +- .../Kernel/arch/armv7/platform_tegra2.c | 32 ++++++++++-- .../Kernel/arch/armv7/platform_tegra2.h | 22 +++++++-- KernelLand/Kernel/arch/armv7/start.S | 14 ++++-- KernelLand/Kernel/arch/armv7/vpci_tegra2.c | 3 +- KernelLand/Kernel/include/vfs_ext.h | 4 +- KernelLand/Modules/Display/Tegra2Vid/main.c | 3 +- KernelLand/Modules/USB/EHCI/ehci.c | 19 +++++-- KernelLand/Modules/armv7/GIC/gic.c | 49 +++++++++++++++---- 9 files changed, 119 insertions(+), 32 deletions(-) diff --git a/KernelLand/Kernel/arch/armv7/main.c b/KernelLand/Kernel/arch/armv7/main.c index d05c01e0..903f5fc7 100644 --- a/KernelLand/Kernel/arch/armv7/main.c +++ b/KernelLand/Kernel/arch/armv7/main.c @@ -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 diff --git a/KernelLand/Kernel/arch/armv7/platform_tegra2.c b/KernelLand/Kernel/arch/armv7/platform_tegra2.c index 36dbb569..0ec90f30 100644 --- a/KernelLand/Kernel/arch/armv7/platform_tegra2.c +++ b/KernelLand/Kernel/arch/armv7/platform_tegra2.c @@ -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 diff --git a/KernelLand/Kernel/arch/armv7/platform_tegra2.h b/KernelLand/Kernel/arch/armv7/platform_tegra2.h index 67f75829..2af310e6 100644 --- a/KernelLand/Kernel/arch/armv7/platform_tegra2.h +++ b/KernelLand/Kernel/arch/armv7/platform_tegra2.h @@ -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 diff --git a/KernelLand/Kernel/arch/armv7/start.S b/KernelLand/Kernel/arch/armv7/start.S index 71534f57..8193b31c 100644 --- a/KernelLand/Kernel/arch/armv7/start.S +++ b/KernelLand/Kernel/arch/armv7/start.S @@ -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] diff --git a/KernelLand/Kernel/arch/armv7/vpci_tegra2.c b/KernelLand/Kernel/arch/armv7/vpci_tegra2.c index 1d01fb0c..9c050064 100644 --- a/KernelLand/Kernel/arch/armv7/vpci_tegra2.c +++ b/KernelLand/Kernel/arch/armv7/vpci_tegra2.c @@ -11,11 +11,10 @@ // === 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, }, diff --git a/KernelLand/Kernel/include/vfs_ext.h b/KernelLand/Kernel/include/vfs_ext.h index a130ac65..1bc3e18a 100644 --- a/KernelLand/Kernel/include/vfs_ext.h +++ b/KernelLand/Kernel/include/vfs_ext.h @@ -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; /** diff --git a/KernelLand/Modules/Display/Tegra2Vid/main.c b/KernelLand/Modules/Display/Tegra2Vid/main.c index 34b58f11..09bbbb87 100644 --- a/KernelLand/Modules/Display/Tegra2Vid/main.c +++ b/KernelLand/Modules/Display/Tegra2Vid/main.c @@ -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); diff --git a/KernelLand/Modules/USB/EHCI/ehci.c b/KernelLand/Modules/USB/EHCI/ehci.c index a2acca2a..c970eb49 100644 --- a/KernelLand/Modules/USB/EHCI/ehci.c +++ b/KernelLand/Modules/USB/EHCI/ehci.c @@ -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; diff --git a/KernelLand/Modules/armv7/GIC/gic.c b/KernelLand/Modules/armv7/GIC/gic.c index 65441791..a918f68e 100644 --- a/KernelLand/Modules/armv7/GIC/gic.c +++ b/KernelLand/Modules/armv7/GIC/gic.c @@ -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; } -- 2.20.1