From f0c5edca2ea6e93a8af7ff3e6505360c884f3323 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 20 Dec 2012 10:04:05 +0800 Subject: [PATCH] Kernel/armv7 - Tegra2 timer and interrupt rework --- KernelLand/Kernel/arch/armv7/Makefile | 2 +- KernelLand/Kernel/arch/armv7/main.c | 3 +- KernelLand/Kernel/arch/armv7/mm_virt.c | 2 +- .../Kernel/arch/armv7/platform_realview_pb.c | 21 +++++ .../Kernel/arch/armv7/platform_tegra2.c | 77 +++++++++++++++++++ .../Kernel/arch/armv7/platform_tegra2.h | 68 ++++++++++++++++ KernelLand/Kernel/arch/armv7/vpci_tegra2.c | 5 +- KernelLand/Modules/armv7/GIC/gic.c | 8 +- 8 files changed, 176 insertions(+), 10 deletions(-) create mode 100644 KernelLand/Kernel/arch/armv7/platform_realview_pb.c create mode 100644 KernelLand/Kernel/arch/armv7/platform_tegra2.c create mode 100644 KernelLand/Kernel/arch/armv7/platform_tegra2.h diff --git a/KernelLand/Kernel/arch/armv7/Makefile b/KernelLand/Kernel/arch/armv7/Makefile index 5429fe66..1d9f4369 100644 --- a/KernelLand/Kernel/arch/armv7/Makefile +++ b/KernelLand/Kernel/arch/armv7/Makefile @@ -12,7 +12,7 @@ LDFLAGS += `$(CC) --print-libgcc-file-name` A_OBJ = start.ao main.o lib.o lib.ao time.o pci.o debug.o A_OBJ += mm_phys.o mm_virt.o proc.o proc.ao -A_OBJ += vpci_$(PLATFORM).o +A_OBJ += vpci_$(PLATFORM).o platform_$(PLATFORM).o #main.c: Makefile.BuildNum.$(ARCH) diff --git a/KernelLand/Kernel/arch/armv7/main.c b/KernelLand/Kernel/arch/armv7/main.c index 248c17c5..d05c01e0 100644 --- a/KernelLand/Kernel/arch/armv7/main.c +++ b/KernelLand/Kernel/arch/armv7/main.c @@ -15,6 +15,7 @@ extern void Arch_LoadBootModules(void); extern void Heap_Install(void); extern void Threads_Init(void); extern void System_Init(const char *Commandline); +extern void Time_Setup(void); // === PROTOTYPES === int kmain(void); @@ -44,7 +45,7 @@ int kmain(void) // LogF("Moving to arch-independent init\n"); #if PLATFORM_is_tegra2 - System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid"); + System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=Tegra2Vid -USB_EHCI:C5000000-14,C5004000-15"); #else System_Init("Acess2.armv7.bin /Acess=initrd: -VTerm:Video=PL110"); #endif diff --git a/KernelLand/Kernel/arch/armv7/mm_virt.c b/KernelLand/Kernel/arch/armv7/mm_virt.c index 146caea8..80034204 100644 --- a/KernelLand/Kernel/arch/armv7/mm_virt.c +++ b/KernelLand/Kernel/arch/armv7/mm_virt.c @@ -10,7 +10,7 @@ #include #define TRACE_MAPS 0 -#define TRACE_COW 1 +#define TRACE_COW 0 #define AP_KRW_ONLY 1 // Kernel page #define AP_KRO_ONLY 5 // Kernel RO page diff --git a/KernelLand/Kernel/arch/armv7/platform_realview_pb.c b/KernelLand/Kernel/arch/armv7/platform_realview_pb.c new file mode 100644 index 00000000..4077f691 --- /dev/null +++ b/KernelLand/Kernel/arch/armv7/platform_realview_pb.c @@ -0,0 +1,21 @@ +/* + * Acess2 Kernel ARMv7 Port + * - By John Hodge (thePowersGang) + * + * platform_realviewpb.c + * - RealviewPB core code + */ +#include + +// === PROTOTYPES === +void Time_Setup(void); + +// === GLOBALS === +tPAddr gGIC_DistributorAddr = 0x1e001000; +tPAddr gGIC_InterfaceAddr = 0x1e000000; + +// === CODE === +void Time_Setup(void) +{ + // TODO: +} diff --git a/KernelLand/Kernel/arch/armv7/platform_tegra2.c b/KernelLand/Kernel/arch/armv7/platform_tegra2.c new file mode 100644 index 00000000..36dbb569 --- /dev/null +++ b/KernelLand/Kernel/arch/armv7/platform_tegra2.c @@ -0,0 +1,77 @@ +/* + * Acess2 Kernel ARMv7 Port + * - By John Hodge (thePowersGang) + * + * platform_tegra2.c + * - Tegra2 Core code + */ +#include +#include "platform_tegra2.h" + +// === CONSTANTS === +#define TIMER0_INT (0*32+0) // Pri #0 +#define TIMER1_INT (0*32+1) // Pri #1 +#define TIMER2_INT (1*32+9) // Sec #9 +#define TIMER3_INT (1*32+10) // Sec #10 + +// === Imports === +extern volatile Sint64 giTimestamp; +extern volatile Uint64 giTicks; +extern volatile Uint64 giPartMiliseconds; +extern void Timer_CallTimers(void); + +// === PROTORTYPES === +void Timer_IRQHandler_SysClock(int IRQ, void *_unused); +void Time_Setup(void); + +// === GLOBALS === +// - Addresses for the GIC to use +tPAddr gGIC_InterfaceAddr = 0x50040000; +tPAddr gGIC_DistributorAddr = 0x50041000; +// - Map of timer registers +struct sTimersMap *gpTimersMap; +// - Interrupt controller code commented out, because the Tegra2 also has a GIC +#if 0 +struct sIRQMap gpIRQMap; +#endif + +// === CODE === + +// -- Timers -- +void Timer_IRQHandler_SysClock(int IRQ, void *_unused) +{ + giTimestamp += 100; + gpTimersMap->TMR0.PCR_0 = (1<<31); +} + +void Time_Setup(void) +{ + gpTimersMap = (void*)MM_MapHWPages(0x60005000, 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 +} + +#if 0 +// -- Interrupt Controller -- +void IRQ_CtrlrHandler(struct sIRQRegs *Ctrlr, int Ofs) +{ + // Primary CPU only? + // TODO: +} + +void IRQ_RootHandler(void) +{ + IRQ_CtrlrHandler(&gpIRQMap->Pri, 0*32); + IRQ_CtrlrHandler(&gpIRQMap->Sec, 1*32); + IRQ_CtrlrHandler(&gpIRQMap->Tri, 2*32); + IRQ_CtrlrHandler(&gpIRQMap->Quad, 3*32); +} + +void IRQ_Setup(void) +{ + gpIRQMap = (void*)MM_MapHWPages(0x60004000, 1); + + gpIRQHandler = IRQ_RootHandler; +} +#endif diff --git a/KernelLand/Kernel/arch/armv7/platform_tegra2.h b/KernelLand/Kernel/arch/armv7/platform_tegra2.h new file mode 100644 index 00000000..67f75829 --- /dev/null +++ b/KernelLand/Kernel/arch/armv7/platform_tegra2.h @@ -0,0 +1,68 @@ +/* + * Acess2 Kernel ARMv7 Port + * - By John Hodge (thePowersGang) + * + * platform_tegra2.c + * - Tegra2 Core code + */ +#ifndef _PLATFORM__TEGRA2_H_ +#define _PLATFORM__TEGRA2_H_ + +struct sTimerRegs +{ + Uint32 PTV_0; // Control / Target value + Uint32 PCR_0; // Current value / IRQ clear +}; +struct sTimersMap +{ + struct sTimerRegs TMR0; + struct sTimerRegs TMR1; + // TMRUS + char _padding[ 0x50-0x10 ]; + + struct sTimerRegs TMR2; + struct sTimerRegs TMR3; +}; + +#if 0 +struct sIRQRegs +{ + Uint32 VIRQ_CPU; + Uint32 VIRQ_COP; + Uint32 VFIQ_CPU; + Uint32 VFIQ_COP; + Uint32 ISR; + Uint32 FIR; // Force interrupt status + Uint32 FIR_SET; // Set bit in FIR + Uint32 FIR_CLR; // Clear bit in FIR + Uint32 CPU_IER; // RO - Interrupt Enable register + Uint32 CPU_IER_SET; + Uint32 CPU_IER_CLR; + Uint32 CPU_IEP; // 1 = FIQ + Uint32 COP_IER; // RO - Interrupt Enable register + Uint32 COP_IER_SET; + Uint32 COP_IER_CLR; + Uint32 COP_IEP; // 1 = FIQ +}; +struct sArbGntRegs +{ + Uint32 CPU_Status; + Uint32 CPU_Enable; + Uint32 COP_Status; + Uint32 COP_Enable; +}; +struct sIRQMap +{ + struct sIRQRegs Pri; + struct sArbGntRegs Arb; + char _pad1[0x100-sizeof(struct sIRQRegs)-sizeof(struct sIRQRegs)]; + struct sIRQRegs Sec; + char _pad2[0x100-sizeof(struct sIRQRegs)]; + struct sIRQRegs Tri; + char _pad3[0x100-sizeof(struct sIRQRegs)]; + struct sIRQRegs Quad; +}; +#endif + +#endif + diff --git a/KernelLand/Kernel/arch/armv7/vpci_tegra2.c b/KernelLand/Kernel/arch/armv7/vpci_tegra2.c index d44e9d58..1d01fb0c 100644 --- a/KernelLand/Kernel/arch/armv7/vpci_tegra2.c +++ b/KernelLand/Kernel/arch/armv7/vpci_tegra2.c @@ -11,9 +11,11 @@ // === GLOBALS === tVPCI_Device gaVPCI_Devices[] = { + // NOTE: USB Controllers moved to command line arguments + #if 0 { .Vendor=0x0ACE,.Device=0x1100, - .Class = 0x0C032000, // Serial, USB, ECHI + .Class = 0x0C032100, // Serial, USB, ECHI .BARs = {0xC5000000,0,0,0,0,0}, .IRQ = 0*32+20, }, @@ -29,6 +31,7 @@ tVPCI_Device gaVPCI_Devices[] = { .BARs = {0xC5008000,0,0,0,0,0}, .IRQ = 4*32+1, } + #endif }; int giVPCI_DeviceCount = sizeof(gaVPCI_Devices)/sizeof(gaVPCI_Devices[0]); diff --git a/KernelLand/Modules/armv7/GIC/gic.c b/KernelLand/Modules/armv7/GIC/gic.c index 8dbab3a3..65441791 100644 --- a/KernelLand/Modules/armv7/GIC/gic.c +++ b/KernelLand/Modules/armv7/GIC/gic.c @@ -16,6 +16,8 @@ // === IMPORTS === extern void *gpIRQHandler; +extern tPAddr gGIC_DistributorAddr; +extern tPAddr gGIC_InterfaceAddr; // === TYPES === typedef void (*tIRQ_Handler)(int, void*); @@ -28,18 +30,12 @@ void GIC_IRQHandler(void); MODULE_DEFINE(0, 0x100, armv7_GIC, GIC_Install, NULL, NULL); Uint32 *gpGIC_DistributorBase; Uint32 *gpGIC_InterfaceBase; -tPAddr gGIC_DistributorAddr; -tPAddr gGIC_InterfaceAddr; tIRQ_Handler gaIRQ_Handlers[N_IRQS]; void *gaIRQ_HandlerData[N_IRQS]; // === CODE === int GIC_Install(char **Arguments) { - // Realview PB - gGIC_InterfaceAddr = 0x1e000000; - gGIC_DistributorAddr = 0x1e001000; - // Initialise gpGIC_InterfaceBase = (void*)MM_MapHWPages(gGIC_InterfaceAddr, 1); LOG("gpGIC_InterfaceBase = %p", gpGIC_InterfaceBase); -- 2.20.1