Kernel/armv7 - Tegra2 timer and interrupt rework
authorJohn Hodge <[email protected]>
Thu, 20 Dec 2012 02:04:05 +0000 (10:04 +0800)
committerJohn Hodge <[email protected]>
Thu, 20 Dec 2012 02:04:05 +0000 (10:04 +0800)
KernelLand/Kernel/arch/armv7/Makefile
KernelLand/Kernel/arch/armv7/main.c
KernelLand/Kernel/arch/armv7/mm_virt.c
KernelLand/Kernel/arch/armv7/platform_realview_pb.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv7/platform_tegra2.c [new file with mode: 0644]
KernelLand/Kernel/arch/armv7/platform_tegra2.h [new file with mode: 0644]
KernelLand/Kernel/arch/armv7/vpci_tegra2.c
KernelLand/Modules/armv7/GIC/gic.c

index 5429fe6..1d9f436 100644 (file)
@@ -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)
 
index 248c17c..d05c01e 100644 (file)
@@ -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
index 146caea..8003420 100644 (file)
@@ -10,7 +10,7 @@
 #include <hal_proc.h>
 
 #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 (file)
index 0000000..4077f69
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * platform_realviewpb.c
+ * - RealviewPB core code
+ */
+#include <acess.h>
+
+// === 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 (file)
index 0000000..36dbb56
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Acess2 Kernel ARMv7 Port
+ * - By John Hodge (thePowersGang)
+ *
+ * platform_tegra2.c
+ * - Tegra2 Core code
+ */
+#include <acess.h>
+#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 (file)
index 0000000..67f7582
--- /dev/null
@@ -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
+
index d44e9d5..1d01fb0 100644 (file)
 
 // === 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]);
 
index 8dbab3a..6544179 100644 (file)
@@ -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);

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