add preliminary clock code that's expected to be set up by fw, gut old arm loader...
authorchristinaa <kristinaa@tuta.io>
Fri, 27 Jan 2017 08:48:00 +0000 (08:48 +0000)
committerchristinaa <kristinaa@tuta.io>
Fri, 27 Jan 2017 08:48:00 +0000 (08:48 +0000)
13 files changed:
BCM2708PlatformStartup.cc
Makefile
arm_chainloader/drivers/sdhost_impl.cc
arm_loader.cc [deleted file]
drivers/BCM2708ArmControl.cc
drivers/BCM2708ClockDomains.cc [new file with mode: 0644]
drivers/BCM2708ClockDomains.hpp [new file with mode: 0644]
drivers/BCM2708Gpio.cc [new file with mode: 0644]
drivers/BCM2708Gpio.hpp [new file with mode: 0644]
drivers/IODevice.hpp
lib/runtime.h
romstage.c
tools/wslstage.py

index 91dc609..16d6ff6 100644 (file)
@@ -8,6 +8,17 @@
 #include <drivers/IODevice.hpp>
 #include <drivers/BCM2708PowerManagement.hpp>
 
+static IODevice* startDeviceByTag(uint32_t tag) {
+       IODevice* dev = IODevice::findByTag(tag);
+
+       if (!dev) {
+               panic("unable to find device with tag 0x%X in the registry", tag);
+       }
+
+       dev->start();
+       return dev;
+}
+
 extern "C" void PEStartPlatform() {
        IODevice* imagePm = PowerManagementDomain::getDeviceForDomain(kCprPowerDomainImage);
        assert(imagePm);
@@ -15,23 +26,18 @@ extern "C" void PEStartPlatform() {
        assert(usbPm);
 
        /*
-        * all devices in the IMAGE domain have to be disabled before
+        * All devices in the IMAGE domain have to be disabled before
         * starting the domain itself.
         */
        usbPm->stop();
-       /*
-        * enable IMAGE power domain.
-        */
+       /* Bring up IMAGE power domain */
        imagePm->start();
-       /*
-        * enable USB power domain.
-        */
+       /* Now we can re-enable USB power domain */
        usbPm->start();
 
-       /*
-        * start up USB PHY.
-        */
-       IODevice* usbPhy = IODevice::findByTag('USBP');
-       assert(usbPhy);
-       usbPhy->start();
+       /* Start USB PHY */
+       startDeviceByTag('USBP');
+
+       /* Start ARM */
+       startDeviceByTag('ARMC');
 }
\ No newline at end of file
index 3f79093..8c98e60 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,6 @@ SRCS = \
        start.s \
        romstage.c \
        sdram.c \
-       arm_loader.c \
        arm_monitor.cc \
        trap.c \
        lib/xprintf.c \
@@ -20,6 +19,9 @@ SRCS = \
        drivers/IODevice.cc \
        drivers/BCM2708PowerManagement.cc \
        drivers/BCM2708UsbPhy.cc \
+       drivers/BCM2708ArmControl.cc \
+       drivers/BCM2708ClockDomains.cc \
+       drivers/BCM2708Gpio.cc \
        BCM2708PlatformStartup.cc \
        chainloader_inc.s
 
index 8406cb1..f5da771 100644 (file)
@@ -62,33 +62,6 @@ SDHOST driver. This used to be known as ALTMMC.
 #define SDHSTS_TRANSFER_ERROR_MASK      (SDHSTS_CRC7_ERROR|SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR)\r
 #define SDHSTS_ERROR_MASK               (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK)\r
 \r
-#define logf(fmt, ...) printf("[GPIO:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);\r
-\r
-enum BCM2708PinmuxSetting {\r
-       kBCM2708PinmuxIn = 0,\r
-       kBCM2708PinmuxOut = 1,\r
-       kBCM2708Pinmux_ALT5 = 2,\r
-       kBCM2708Pinmux_ALT4 = 3,\r
-       kBCM2708Pinmux_ALT0 = 4,\r
-       kBCM2708Pinmux_ALT1 = 5,\r
-       kBCM2708Pinmux_ALT2 = 6,\r
-       kBCM2708Pinmux_ALT3 = 7\r
-};\r
-\r
-struct BCM2708GPIO {\r
-\r
-       static void set(uint32_t pin_num, BCM2708PinmuxSetting setting) {\r
-               uint32_t* fsel = reinterpret_cast<uint32_t*>(\r
-                                    reinterpret_cast<uint32_t>(&GP_FSEL0) + (0x4 * (pin_num/10))\r
-                                );\r
-               uint32_t pin_shift = (pin_num % 10) * 3;\r
-\r
-\r
-\r
-       }\r
-};\r
-\r
-#undef logf\r
 #define logf(fmt, ...) printf("[EMMC:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);\r
 \r
 #define kIdentSafeClockRate 0x148\r
diff --git a/arm_loader.cc b/arm_loader.cc
deleted file mode 100644 (file)
index 552e693..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*=============================================================================\r
-Copyright (C) 2016-2017 Authors of rpi-open-firmware\r
-All rights reserved.\r
-\r
-This program is free software; you can redistribute it and/or\r
-modify it under the terms of the GNU General Public License\r
-as published by the Free Software Foundation; either version 2\r
-of the License, or (at your option) any later version.\r
-\r
-This program is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-FILE DESCRIPTION\r
-ARM initialization stuff.\r
-\r
-=============================================================================*/\r
-\r
-#include <lib/runtime.h>\r
-#include <drivers/BCM2708PowerManagement.hpp>\r
-\r
-#define logf(fmt, ...) printf("[ARMLDR:%s]: " fmt, __FUNCTION__, ##__VA_ARGS__);\r
-\r
-extern uint32_t g_CPUID;\r
-extern uint32_t g_RAMSize;\r
-\r
-extern uint8_t L_arm_code_start;\r
-extern uint8_t L_arm_code_end;\r
-\r
-#define ARM_MEMORY_BASE 0xC0000000\r
-#define ARM_BKPT_OPCODE 0xE1200070\r
-\r
-/*\r
- * RPi3: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488d/CIHBDCJD.html\r
- */\r
-\r
-/*\r
- * This controls AA64nAA32 signal, when set, ARM starts in AArch64 mode. Only applicable\r
- * to systems using Cortex-A53.\r
- */\r
-#define ARM_C0_AARCH64 0x00000200\r
-\r
-/* XXX: What is this? */\r
-#define PM_UNK_CFG_CLR 0xFFFCFFFF\r
-\r
-static inline void assert_global_reset() {\r
-       PowerManagementDomain::getDeviceForDomain(kCprPowerDomainARM)->setReset();\r
-}\r
-\r
-static void enable_power() {\r
-       PowerManagementDomain* armPm = PowerManagementDomain::getDeviceForDomain(kCprPowerDomainARM);\r
-       assert(armPm);\r
-       armPm->start();\r
-}\r
-\r
-static void bresp_cycle_write(uint32_t bits) {\r
-       ARM_CONTROL0 = (ARM_CONTROL0 & ~(ARM_C0_BRESP1|ARM_C0_BRESP2)) | bits;\r
-       printf("0x%X,", bits);\r
-       udelay(30);\r
-}\r
-\r
-static uint32_t g_BrespTab[] = {\r
-       0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x1C, 0x18, 0x1C, 0x18, 0x0,\r
-       0x10, 0x14, 0x10, 0x1C, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x0,\r
-       0x10, 0x14, 0x10, 0x1C, 0x18, 0x1C, 0x10, 0x14, 0x18, 0x1C, 0x10, 0x14, 0x10, 0x0,\r
-       0x10, 0x14, 0x18, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x0,\r
-       0x10, 0x14, 0x18, 0x14, 0x18, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x18, 0x0\r
-};\r
-static void do_bresp_cycle() {\r
-       /* my little axi - peripherals are magic */\r
-       logf("Cycling AXI bits ...\n\t");\r
-\r
-       for (int i = 0; i < sizeof(g_BrespTab)/sizeof(g_BrespTab[0]); i++) {\r
-               bresp_cycle_write(g_BrespTab[i]);\r
-\r
-               if (i && ((i % 14) == 0))\r
-                       printf("\n\t");\r
-       }\r
-\r
-       printf("\n");\r
-}\r
-\r
-void setup_bridge(bool bresp_cycle) {\r
-       logf("setting up async bridge ...\n");\r
-\r
-       if (bresp_cycle) {\r
-               assert_global_reset();\r
-               do_bresp_cycle();\r
-               assert_global_reset();\r
-               udelay(300);\r
-       }\r
-\r
-       logf("starting async bridge, ARM should be able to communicate through AXI ...\n");\r
-       ARM_CONTROL1 &= ~ARM_C1_REQSTOP;\r
-       udelay(300);\r
-\r
-       if (!bresp_cycle)\r
-               assert_global_reset();\r
-\r
-       logf("bridge init done, PM_PROC is now: 0x%X!\n", PM_PROC);\r
-}\r
-\r
-static void set_clock_source(unsigned int source) {\r
-       CM_ARMCTL = CM_PASSWORD | source | CM_ARMCTL_ENAB_SET;\r
-}\r
-\r
-static void enable_clock() {\r
-       logf("initializing PLLB ...\n");\r
-\r
-       /* oscillator->pllb */\r
-       A2W_XOSC_CTRL |= A2W_PASSWORD | A2W_XOSC_CTRL_PLLBEN_SET;\r
-\r
-       A2W_PLLB_FRAC = A2W_PASSWORD | 0xeaaa8;\r
-       A2W_PLLB_CTRL = A2W_PASSWORD | 48 | 0x1000;\r
-\r
-       CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET;\r
-       CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET | CM_PLLB_HOLDARM_SET;\r
-\r
-       A2W_PLLB_ANA3 = A2W_PASSWORD | 0x100;\r
-       A2W_PLLB_ANA2 = A2W_PASSWORD | 0x0;\r
-       A2W_PLLB_ANA1 = A2W_PASSWORD | 0x140000;\r
-       A2W_PLLB_ANA0 = A2W_PASSWORD | 0x0;\r
-\r
-       A2W_PLLB_DIG3 = A2W_PASSWORD | 0x0;\r
-       A2W_PLLB_DIG2 = A2W_PASSWORD | 0x400000;\r
-       A2W_PLLB_DIG1 = A2W_PASSWORD | 0x3a;\r
-       A2W_PLLB_DIG0 = A2W_PASSWORD | 48 | 0xAAA000;\r
-\r
-       A2W_PLLB_CTRL = A2W_PASSWORD | 48 | 0x21000;\r
-\r
-       A2W_PLLB_DIG3 = A2W_PASSWORD | 0x2;\r
-       A2W_PLLB_DIG2 = A2W_PASSWORD | 0x402401;\r
-       A2W_PLLB_DIG1 = A2W_PASSWORD | 0x403a;\r
-       A2W_PLLB_DIG0 = A2W_PASSWORD | 48 | 0xAAA000;\r
-\r
-       A2W_PLLB_ARM = A2W_PASSWORD | 2;\r
-\r
-       CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET | CM_PLLB_HOLDARM_SET | CM_PLLB_LOADARM_SET;\r
-       CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET | CM_PLLB_HOLDARM_SET;\r
-       CM_PLLB = CM_PASSWORD;\r
-\r
-       set_clock_source(4);\r
-\r
-       logf("KAIP  = 0x%X\n", A2W_PLLB_ANA_KAIP);\r
-       logf("MULTI = 0x%X\n", A2W_PLLB_ANA_MULTI);\r
-\r
-       logf("ARM clock succesfully initialized!\n");\r
-}\r
-\r
-static void arm_load_code() {\r
-       uint32_t* mem = (uint32_t*)(ARM_MEMORY_BASE);\r
-\r
-       uint8_t* start = &L_arm_code_start;\r
-       uint8_t* end = &L_arm_code_end;\r
-       uint32_t size = (uint32_t)(end - start);\r
-\r
-       bcopy(start, mem, size);\r
-\r
-       logf("copied %d bytes to 0x%X!\n", size, ARM_MEMORY_BASE);\r
-\r
-       /* verify */\r
-       for (int i = 0; i < size; i++) {\r
-               uint8_t* mem8 = (uint8_t*)(mem);\r
-               if (start[i] != mem8[i])\r
-                       panic("copy failed at 0x%X expected 0x%X, got 0x%X", (uint32_t)&mem8[i],\r
-                             *((uint32_t*)&mem8[i]),\r
-                             *((uint32_t*)&start[i]));\r
-       }\r
-}\r
-\r
-static void arm_pmap_enter(uint32_t bus_address, uint32_t arm_address) {\r
-       volatile uint32_t* tte = reinterpret_cast<volatile uint32_t*>(&ARM_TRANSLATE);\r
-\r
-       uint32_t index = arm_address >> 24;\r
-       uint32_t pte = bus_address >> 21;\r
-\r
-       tte[index] = pte;\r
-\r
-       //logf("Translation: [0x%X => 0x%X] 0x%X => 0x%X\n", index * 4, bus_address >> 21, bus_address, arm_address);\r
-}\r
-\r
-/*\r
-#define ARM_C0_PRIO_PER  0x00F00000 // per priority mask\r
-#define ARM_C0_PRIO_L2   0x0F000000\r
-#define ARM_C0_PRIO_UC   0xF0000000\r
- */\r
-\r
-static void patch_arm_firmware_data() {\r
-       volatile firmware_arm_data_t* firmware_data = reinterpret_cast<firmware_arm_data_t*>(ARM_MEMORY_BASE + 32);\r
-\r
-       firmware_data->sdram_size = g_RAMSize;\r
-       firmware_data->vpu_cpuid = g_CPUID;\r
-}\r
-\r
-static void arm_enable_tzpc() {\r
-       /*\r
-        * enable SDRAM security.\r
-        * mask: 0xffffe000\r
-        */\r
-       logf("configuring secure SDRAM ...\n");\r
-       SD_SECSRT0 = 0xC0000000;\r
-       SD_SECEND0 = 0xC0011FFF;\r
-       logf("enabling secure SDRAM ...\n");\r
-       SD_SECSRT0 = 0xC0000001;\r
-       logf("secure SDRAM enabled ...\n");\r
-}\r
-\r
-extern "C" void arm_init() {\r
-       logf("arm init started\n");\r
-\r
-       arm_load_code();\r
-       patch_arm_firmware_data();\r
-\r
-       //arm_enable_tzpc();\r
-\r
-       logf("original memstart: 0x%X\n", *((volatile uint32_t*)ARM_MEMORY_BASE));\r
-\r
-       for (uint32_t i = 0; i < 62; i++) {\r
-               uint32_t offset = i * 0x1000000;\r
-               arm_pmap_enter(ARM_MEMORY_BASE + offset, 0x0 + offset);\r
-       }\r
-\r
-       logf("mapped VC 0x%X to ARM 0x%X\n", ARM_MEMORY_BASE, 0);\r
-\r
-       arm_pmap_enter(VC4_PERIPH_BASE, ARM_PERIPH_BASE);\r
-\r
-       logf("mapped peripherals VC 0x%X to ARM 0x%X\n", VC4_PERIPH_BASE, ARM_PERIPH_BASE);\r
-\r
-       /* see if the ARM block is responding */\r
-       logf("ARM ID: 0x%X C0: 0x%X\n", ARM_ID, ARM_CONTROL0);\r
-\r
-       /*\r
-        * enable peripheral access, map arm secure bits to axi secure bits 1:1 and\r
-        * set the mem size for who knows what reason.\r
-        */\r
-       ARM_CONTROL0 |= 0x008 | ARM_C0_APROTPASS | ARM_C0_SIZ1G | ARM_C0_FULLPERI;\r
-       ARM_CONTROL1 |= ARM_C1_PERSON;\r
-\r
-       ARM_IRQ_ENBL3 |= ARM_IE_MAIL;\r
-\r
-       logf("using C0: 0x%X\n", ARM_CONTROL0);\r
-\r
-       enable_clock();\r
-       enable_power();\r
-       /* start io bridge */\r
-       setup_bridge(true);\r
-}\r
index 9ef7dff..9f70064 100644 (file)
 
 #include <drivers/IODevice.hpp>
 #include <drivers/BCM2708PowerManagement.hpp>
+#include <drivers/BCM2708ClockDomains.hpp>
 
 #define FLAG_BUSY (1 << 31)
 
+extern uint32_t g_CPUID;
+extern uint32_t g_RAMSize;
+
+extern uint8_t L_arm_code_start;
+extern uint8_t L_arm_code_end;
+
+#define ARM_MEMORY_BASE 0xC0000000
+#define ARM_BKPT_OPCODE 0xE1200070
+
+/*
+ * RPi3: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0488d/CIHBDCJD.html
+ */
+
+/*
+ * This controls AA64nAA32 signal, when set, ARM starts in AArch64 mode. Only applicable
+ * to systems using Cortex-A53.
+ */
+#define ARM_C0_AARCH64 0x00000200
+
+static uint32_t g_BrespTab[] = {
+       0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x1C, 0x18, 0x1C, 0x18, 0x0,
+       0x10, 0x14, 0x10, 0x1C, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x0,
+       0x10, 0x14, 0x10, 0x1C, 0x18, 0x1C, 0x10, 0x14, 0x18, 0x1C, 0x10, 0x14, 0x10, 0x0,
+       0x10, 0x14, 0x18, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x0,
+       0x10, 0x14, 0x18, 0x14, 0x18, 0x14, 0x10, 0x14, 0x10, 0x14, 0x10, 0x14, 0x18, 0x0
+};
+
 struct BCM2708ArmControl : IODevice {
        IODriverConstructor(BCM2708ArmControl);
 
+       PowerManagementDomain* pmDomain;
+
+       static inline void bridgeWriteBresp(uint32_t bits) {
+               ARM_CONTROL0 = (ARM_CONTROL0 & ~(ARM_C0_BRESP1|ARM_C0_BRESP2)) | bits;
+               udelay(30);
+       }
+
+       void bridgeCycleBresp() {
+               IODriverLog("cycling through bresp bits ...");
+               for (int i = 0; i < sizeof(g_BrespTab)/sizeof(g_BrespTab[0]); i++) {
+                       bridgeWriteBresp(g_BrespTab[i]);
+               }
+       }
+
+       void bridgeStart(bool cycleBrespBits) {
+               IODriverLog("setting up async bridge ...");
+
+               if (cycleBrespBits) {
+                       pmDomain->setReset();
+                       bridgeCycleBresp();
+                       pmDomain->setReset();
+
+                       udelay(300);
+               }
+
+               IODriverLog("starting async bridge now!");
+               ARM_CONTROL1 &= ~ARM_C1_REQSTOP;
+               udelay(300);
+
+               if (!cycleBrespBits)
+                       pmDomain->setReset();
+
+               IODriverLog("bridge init done, PM_PROC is now: 0x%X!", PM_PROC);
+       }
+
+       void setupClock() {
+               IODriverLog("initializing PLLB ...");
+
+               /* oscillator->pllb */
+               A2W_XOSC_CTRL |= A2W_PASSWORD | A2W_XOSC_CTRL_PLLBEN_SET;
+
+               A2W_PLLB_FRAC = A2W_PASSWORD | 0xeaaa8;
+               A2W_PLLB_CTRL = A2W_PASSWORD | 48 | 0x1000;
+
+               CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET;
+               CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET | CM_PLLB_HOLDARM_SET;
+
+               A2W_PLLB_ANA3 = A2W_PASSWORD | 0x100;
+               A2W_PLLB_ANA2 = A2W_PASSWORD | 0x0;
+               A2W_PLLB_ANA1 = A2W_PASSWORD | 0x140000;
+               A2W_PLLB_ANA0 = A2W_PASSWORD | 0x0;
+
+               BCM2708VCO* pllb = static_cast<BCM2708VCO*>(IODevice::findByTag('PLLB'));
+               assert(pllb);
+               pllb->setDigValues();
+
+               A2W_PLLB_ARM = A2W_PASSWORD | 2;
+
+               CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET | CM_PLLB_HOLDARM_SET | CM_PLLB_LOADARM_SET;
+               CM_PLLB = CM_PASSWORD | CM_PLLB_DIGRST_SET | CM_PLLB_ANARST_SET | CM_PLLB_HOLDARM_SET;
+               CM_PLLB = CM_PASSWORD;
+
+               CM_ARMCTL = CM_PASSWORD | 4 | CM_ARMCTL_ENAB_SET;
+
+               IODriverLog("KAIP  = 0x%X", A2W_PLLB_ANA_KAIP); /* 0x228 */
+               IODriverLog("MULTI = 0x%X", A2W_PLLB_ANA_MULTI); /* 0x613277 */
+
+               IODriverLog("ARM clock succesfully initialized!");
+       }
+
+       void patchFirmwareData() {
+               volatile firmware_arm_data_t* firmware_data = reinterpret_cast<firmware_arm_data_t*>(ARM_MEMORY_BASE + 32);
+
+               firmware_data->sdram_size = g_RAMSize;
+               firmware_data->vpu_cpuid = g_CPUID;
+       }
+
+       void loadInitialCode() {
+               uint32_t* mem = (uint32_t*)(ARM_MEMORY_BASE);
+
+               uint8_t* start = &L_arm_code_start;
+               uint8_t* end = &L_arm_code_end;
+               uint32_t size = (uint32_t)(end - start);
+
+               bcopy(start, mem, size);
+
+               IODriverLog("copied %d bytes to 0x%X!", size, ARM_MEMORY_BASE);
+
+               /* verify */
+               for (int i = 0; i < size; i++) {
+                       uint8_t* mem8 = (uint8_t*)(mem);
+                       if (start[i] != mem8[i])
+                               panic("copy failed at 0x%X expected 0x%X, got 0x%X", (uint32_t)&mem8[i],
+                                     *((uint32_t*)&mem8[i]),
+                                     *((uint32_t*)&start[i]));
+               }
+
+               patchFirmwareData();
+       }
+
+       void mapBusToArm(uint32_t busAddr, uint32_t armAddr) {
+               volatile uint32_t* tte = reinterpret_cast<volatile uint32_t*>(&ARM_TRANSLATE);
+
+               uint32_t index = armAddr >> 24;
+               uint32_t pte = busAddr >> 21;
+
+               tte[index] = pte;
+       }
+
        virtual void start() override {
                IODriverLog("starting ...");
 
+               pmDomain = PowerManagementDomain::getDeviceForDomain(kCprPowerDomainARM);
+               assert(pmDomain);
+
+               loadInitialCode();
+
+               IODriverLog("original memstart: 0x%X", *((volatile uint32_t*)ARM_MEMORY_BASE));
+
+               for (uint32_t i = 0; i < 62; i++) {
+                       uint32_t offset = i * 0x1000000;
+                       mapBusToArm(ARM_MEMORY_BASE + offset, 0x0 + offset);
+               }
+
+               IODriverLog("mapped VC 0x%X to ARM 0x%X", ARM_MEMORY_BASE, 0);
+
+               mapBusToArm(VC4_PERIPH_BASE, ARM_PERIPH_BASE);
+
+               IODriverLog("mapped peripherals VC 0x%X to ARM 0x%X", VC4_PERIPH_BASE, ARM_PERIPH_BASE);
+
+               /* see if the ARM block is responding */
+               IODriverLog("ARM ID: 0x%X C0: 0x%X", ARM_ID, ARM_CONTROL0);
+
+               /*
+                * enable peripheral access, map arm secure bits to axi secure bits 1:1 and
+                * set the mem size for who knows what reason.
+                */
+               ARM_CONTROL0 |= 0x008 | ARM_C0_APROTPASS | ARM_C0_SIZ1G | ARM_C0_FULLPERI;
+               ARM_CONTROL1 |= ARM_C1_PERSON;
+
+               ARM_IRQ_ENBL3 |= ARM_IE_MAIL;
+
+               IODriverLog("using C0: 0x%X", ARM_CONTROL0);
+
+               setupClock();
+               pmDomain->start();
+
+               /*
+                * ARM is now powered on but stalling on a bus transaction, start the
+                * async bridge and let ARM start fetching instructions.
+                */
+               bridgeStart(true);
+
                IODevice::start();
        }
 
        virtual void init() override {
-               setName("BCM2708ArmControl");
                setTag('ARMC');
        }
 };
diff --git a/drivers/BCM2708ClockDomains.cc b/drivers/BCM2708ClockDomains.cc
new file mode 100644 (file)
index 0000000..f496b97
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * VideoCore4_Drivers
+ * Copyright (c) 2017 Kristina Brooks
+ *
+ * PLL VCOs and their channels.
+ */
+
+#include <drivers/BCM2708ClockDomains.hpp>
+
+/*
+PLL/Channel tree:
+|-XOSC
+ |-PLLA
+   |-CORE
+   |-PER
+   |-CCP2
+   |-DSI0
+ |-PLLB
+   |-ARM
+     |-ARM Clock (CM_ARM*)
+   |-SP0 (???)
+   |-SP1 (???)
+   |-SP2 (???)
+ |-PLLC
+   |-CORE0
+   |-CORE1
+   |-PER
+   |-CORE2 (???)
+ |-PLLD
+   |-DSI0
+   |-DSI1
+   |-CORE
+   |-PER
+ |-PLLH
+   |-AUX
+   |-PIX
+   |-RCAL
+   |-STS
+ */
+
+/***********************************************************************
+ * 
+ * Common VCO stuff.
+ *
+ ***********************************************************************/
+
+void BCM2708VCO::setDigValues() {
+       IODriverLog("setting DIG values for this VCO ...");
+
+       uint32_t dig0 = dig[0],
+               dig1 = dig[1],
+               dig2 = dig[2],
+               dig3 = dig[3];
+
+       /* 0xAA covers all possible HOLD bits in CM_PLLx regs */
+       *cmPllCtrl = CM_PASSWORD | 0xAA;
+       
+       dig[3] = A2W_PASSWORD | (dig3);
+       dig[2] = A2W_PASSWORD | (dig2 & 0xFFEFFBFE);
+       dig[1] = A2W_PASSWORD | (dig1 & ~(1 << 14));
+       dig[0] = A2W_PASSWORD | (dig0);
+
+       *ctrl = A2W_PASSWORD | 0x20000 | *ctrl;
+
+       dig3 |= 0x42;
+
+       dig[3] = A2W_PASSWORD | (dig3);
+       dig[2] = A2W_PASSWORD | (dig2);
+       dig[1] = A2W_PASSWORD | (dig1);
+       dig[0] = A2W_PASSWORD | (dig0);
+}
+
+void BCM2708VCO::dumpDigValues() {
+       IODriverLog("DIG0: 0x%X, DIG1: 0x%X, DIG2: 0x%X, DIG3: 0x%X",
+               dig[0],
+               dig[1],
+               dig[2],
+               dig[3]);
+}
+
+/***********************************************************************
+ * 
+ * PLL VCOs for specific PLLs.
+ *
+ ***********************************************************************/
+
+struct BCM2708PLLB : BCM2708VCO {
+       IODriverConstructor(BCM2708PLLB);
+
+       /*
+        * Working: DIG0: 0xAAA030, DIG1: 0x403A, DIG2: 0x402401, DIG3: 0x2
+        */
+
+       virtual void init() override {
+               ctrl = RegToRef(A2W_PLLB_CTRL);
+               ana = RegToRef(A2W_PLLB_ANA0);
+               dig = RegToRef(A2W_PLLB_DIG0);
+               cmPllCtrl = RegToRef(CM_PLLB);
+
+               IODriverLog("PLLB VCO registered");
+
+               setTag('PLLB');
+       }
+};
+IODriverCreateSingletonInstance(BCM2708PLLB);
+
+/***********************************************************************
+ * 
+ * ARM Clock.
+ *
+ ***********************************************************************/
+
+struct BCM2708ClockDomain : IODevice {
+       volatile uint32_t* cmDiv;
+       volatile uint32_t* cmCtrl;
+};
+
+struct BCM2708ArmClockDomain : BCM2708ClockDomain {
+       
+};
diff --git a/drivers/BCM2708ClockDomains.hpp b/drivers/BCM2708ClockDomains.hpp
new file mode 100644 (file)
index 0000000..a8f1ea2
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * VideoCore4_Drivers
+ * Copyright (c) 2017 Kristina Brooks
+ *
+ * PLL VCOs and their channels.
+ */
+
+#pragma once
+#include <drivers/IODevice.hpp>
+
+struct BCM2708VCO : IODevice {
+       volatile uint32_t* dig;
+       volatile uint32_t* ana;
+       volatile uint32_t* ctrl;
+       volatile uint32_t* cmPllCtrl;
+
+       void setDigValues();
+       void dumpDigValues();
+};
\ No newline at end of file
diff --git a/drivers/BCM2708Gpio.cc b/drivers/BCM2708Gpio.cc
new file mode 100644 (file)
index 0000000..a6c7c09
--- /dev/null
@@ -0,0 +1,16 @@
+#include <drivers/BCM2708Gpio.hpp>
+
+void BCM2708Gpio::setFunction(uint32_t pin_num, BCM2708PinmuxSetting function) {
+       uint32_t* fsel = reinterpret_cast<uint32_t*>(
+                                    reinterpret_cast<uint32_t>(&GP_FSEL0) + (0x4 * (pin_num/10))
+                                );
+       uint32_t pin_shift = (pin_num % 10) * 3;
+
+       *fsel = (*fsel & (0x7 << pin_shift)) | function;
+}
+
+void BCM2708Gpio::init() {
+       setTag('GPIO');
+}
+
+IODriverCreateSingletonInstance(BCM2708Gpio);
\ No newline at end of file
diff --git a/drivers/BCM2708Gpio.hpp b/drivers/BCM2708Gpio.hpp
new file mode 100644 (file)
index 0000000..4622b12
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * VideoCore4_Drivers
+ * Copyright (c) 2017 Authors of rpi-open-firmware
+ *
+ * USB PHY initialization driver.
+ */
+
+#include <drivers/IODevice.hpp>
+
+enum BCM2708PinmuxSetting {
+       kBCM2708PinmuxIn = 0,
+       kBCM2708PinmuxOut = 1,
+       kBCM2708Pinmux_ALT5 = 2,
+       kBCM2708Pinmux_ALT4 = 3,
+       kBCM2708Pinmux_ALT0 = 4,
+       kBCM2708Pinmux_ALT1 = 5,
+       kBCM2708Pinmux_ALT2 = 6,
+       kBCM2708Pinmux_ALT3 = 7
+};
+
+struct BCM2708Gpio : IODevice {
+       IODriverConstructor(BCM2708Gpio);
+
+       void setFunction(uint32_t pin, BCM2708PinmuxSetting function);
+       virtual void init();
+};
\ No newline at end of file
index 240c7ff..f3636ad 100644 (file)
@@ -43,4 +43,4 @@ struct IODevice {
 
 #define IODriverLog(fmt, ...) driverLog(__FUNCTION__, fmt, ##__VA_ARGS__)
 #define IODriverCreateSingletonInstance(clazz) static clazz __IODriver_static_ ## clazz {}
-#define IODriverConstructor(clazz) clazz() { _beforeInit(); init(); _afterInit(); }
\ No newline at end of file
+#define IODriverConstructor(clazz) inline clazz() { _beforeInit(); driverName = #clazz; init(); _afterInit(); }
\ No newline at end of file
index e34aea5..5861dfa 100644 (file)
@@ -23,6 +23,8 @@
 extern "C" {
 #endif
 
+#define RegToRef(x) reinterpret_cast<volatile uint32_t*>(&x)
+
 extern void udelay(uint32_t time);
 extern void __cxx_init();
 
index 310b5c1..fd88544 100644 (file)
@@ -201,9 +201,6 @@ int _main(unsigned int cpuid, unsigned int load_address) {
 \r
        PEStartPlatform();\r
 \r
-       /* bring up ARM */\r
-       arm_init();\r
-\r
        /* start vpu monitor */\r
        monitor_start();\r
 \r
index cf6c79b..d52f3a7 100644 (file)
@@ -9,7 +9,7 @@ import subprocess
 import os
 from StringIO import StringIO
 
-disk_name = 'E'
+disk_name = 'F'
 disk_ready = False
 wmic_output = os.popen('wcmd wmic logicaldisk get caption, filesystem')
 
This page took 0.060667 seconds and 4 git commands to generate.