]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - bootrom/bootrom.c
missing parameter in 'threshold' command help
[proxmark3-svn] / bootrom / bootrom.c
index c8c695cc9f6c097b4b7b4f70771ff02711e0c7b6..c0522dfad66bd89023a4256ca3cfe4a100df659a 100644 (file)
@@ -1,7 +1,7 @@
 #include <proxmark3.h>\r
 \r
 struct common_area common_area __attribute__((section(".commonarea")));\r
-unsigned int start_addr, end_addr, bootrom_unlocked; \r
+unsigned int start_addr, end_addr, bootrom_unlocked;\r
 extern char _bootrom_start, _bootrom_end, _flash_start, _flash_end;\r
 \r
 static void ConfigClocks(void)\r
@@ -10,53 +10,57 @@ static void ConfigClocks(void)
     // slow clock runs at 32Khz typical regardless of crystal\r
 \r
     // enable system clock and USB clock\r
-    PMC_SYS_CLK_ENABLE = PMC_SYS_CLK_PROCESSOR_CLK | PMC_SYS_CLK_UDP_CLK;\r
+    AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK | AT91C_PMC_UDP;\r
 \r
        // enable the clock to the following peripherals\r
-    PMC_PERIPHERAL_CLK_ENABLE =\r
-        (1<<PERIPH_PIOA) |\r
-        (1<<PERIPH_ADC) |\r
-        (1<<PERIPH_SPI) |\r
-        (1<<PERIPH_SSC) |\r
-        (1<<PERIPH_PWMC) |\r
-        (1<<PERIPH_UDP);\r
+    AT91C_BASE_PMC->PMC_PCER =\r
+               (1<<AT91C_ID_PIOA)      |\r
+               (1<<AT91C_ID_ADC)       |\r
+               (1<<AT91C_ID_SPI)       |\r
+               (1<<AT91C_ID_SSC)       |\r
+               (1<<AT91C_ID_PWMC)      |\r
+               (1<<AT91C_ID_UDP);\r
 \r
        // worst case scenario, with 16Mhz xtal startup delay is 14.5ms\r
        // with a slow clock running at it worst case (max) frequency of 42khz\r
        // max startup delay = (14.5ms*42k)/8 = 76 = 0x4C round up to 0x50\r
 \r
        // enable main oscillator and set startup delay\r
-    PMC_MAIN_OSCILLATOR = PMC_MAIN_OSCILLATOR_ENABLE |\r
-        PMC_MAIN_OSCILLATOR_STARTUP_DELAY(0x50);\r
+    AT91C_BASE_PMC->PMC_MOR =\r
+       PMC_MAIN_OSC_ENABLE |\r
+        PMC_MAIN_OSC_STARTUP_DELAY(0x50);\r
 \r
        // wait for main oscillator to stabilize\r
-       while ( !(PMC_INTERRUPT_STATUS & PMC_MAIN_OSCILLATOR_STABILIZED) )\r
+       while ( !(AT91C_BASE_PMC->PMC_SR & PMC_MAIN_OSC_STABILIZED) )\r
                ;\r
 \r
     // minimum PLL clock frequency is 80 MHz in range 00 (96 here so okay)\r
     // frequency is crystal * multiplier / divisor = 16Mhz * 12 / 2 = 96Mhz\r
-    PMC_PLL = PMC_PLL_DIVISOR(2) | PMC_PLL_COUNT_BEFORE_LOCK(0x50) |\r
-        PMC_PLL_FREQUENCY_RANGE(0) | PMC_PLL_MULTIPLIER(12) |\r
-        PMC_PLL_USB_DIVISOR(1);\r
+    AT91C_BASE_PMC->PMC_PLLR =\r
+       PMC_PLL_DIVISOR(2) |\r
+               PMC_PLL_COUNT_BEFORE_LOCK(0x50) |\r
+               PMC_PLL_FREQUENCY_RANGE(0) |\r
+               PMC_PLL_MULTIPLIER(12) |\r
+               PMC_PLL_USB_DIVISOR(1);\r
 \r
        // wait for PLL to lock\r
-       while ( !(PMC_INTERRUPT_STATUS & PMC_MAIN_OSCILLATOR_PLL_LOCK) )\r
+       while ( !(AT91C_BASE_PMC->PMC_SR & PMC_MAIN_OSC_PLL_LOCK) )\r
                ;\r
 \r
        // we want a master clock (MCK) to be PLL clock / 2 = 96Mhz / 2 = 48Mhz\r
        // as per datasheet, this register must be programmed in two operations\r
        // when changing to PLL, program the prescaler first then the source\r
-    PMC_MASTER_CLK = PMC_CLK_PRESCALE_DIV_2;\r
+    AT91C_BASE_PMC->PMC_MCKR = PMC_CLK_PRESCALE_DIV_2;\r
 \r
        // wait for main clock ready signal\r
-       while ( !(PMC_INTERRUPT_STATUS & PMC_MAIN_OSCILLATOR_MCK_READY) )\r
+       while ( !(AT91C_BASE_PMC->PMC_SR & PMC_MAIN_OSC_MCK_READY) )\r
                ;\r
 \r
        // set the source to PLL\r
-    PMC_MASTER_CLK = PMC_CLK_SELECTION_PLL_CLOCK | PMC_CLK_PRESCALE_DIV_2;\r
+    AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | PMC_CLK_PRESCALE_DIV_2;\r
 \r
        // wait for main clock ready signal\r
-       while ( !(PMC_INTERRUPT_STATUS & PMC_MAIN_OSCILLATOR_MCK_READY) )\r
+       while ( !(AT91C_BASE_PMC->PMC_SR & PMC_MAIN_OSC_MCK_READY) )\r
                ;\r
 }\r
 \r
@@ -79,19 +83,19 @@ void UsbPacketReceived(BYTE *packet, int len)
         case CMD_DEVICE_INFO:\r
             dont_ack = 1;\r
             c->cmd = CMD_DEVICE_INFO;\r
-            c->ext1 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | \r
+            c->arg[0] = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM |\r
                 DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;\r
-            if(common_area.flags.osimage_present) c->ext1 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;\r
+            if(common_area.flags.osimage_present) c->arg[0] |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;\r
             UsbSendPacket(packet, len);\r
             break;\r
 \r
         case CMD_SETUP_WRITE:\r
             /* The temporary write buffer of the embedded flash controller is mapped to the\r
-             * whole memory region, only the last 8 bits are decoded.
+             * whole memory region, only the last 8 bits are decoded.\r
              */\r
             p = (volatile DWORD *)&_flash_start;\r
             for(i = 0; i < 12; i++) {\r
-                p[i+c->ext1] = c->d.asDwords[i];\r
+                p[i+c->arg[0]] = c->d.asDwords[i];\r
             }\r
             break;\r
 \r
@@ -102,39 +106,47 @@ void UsbPacketReceived(BYTE *packet, int len)
             }\r
 \r
             /* Check that the address that we are supposed to write to is within our allowed region */\r
-            if( ((c->ext1+FLASH_PAGE_SIZE_BYTES-1) >= end_addr) || (c->ext1 < start_addr) ) {\r
+            if( ((c->arg[0]+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (c->arg[0] < start_addr) ) {\r
                 /* Disallow write */\r
                 dont_ack = 1;\r
                 c->cmd = CMD_NACK;\r
                 UsbSendPacket(packet, len);\r
             } else {\r
                 /* Translate address to flash page and do flash, update here for the 512k part */\r
-                MC_FLASH_COMMAND = MC_FLASH_COMMAND_KEY |\r
-                    MC_FLASH_COMMAND_PAGEN((c->ext1-(int)&_flash_start)/FLASH_PAGE_SIZE_BYTES) |\r
-                    FCMD_WRITE_PAGE;\r
+                AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |\r
+                    MC_FLASH_COMMAND_PAGEN((c->arg[0]-(int)&_flash_start)/AT91C_IFLASH_PAGE_SIZE) |\r
+                    AT91C_MC_FCMD_START_PROG;\r
             }\r
-            while(!(MC_FLASH_STATUS & MC_FLASH_STATUS_READY))\r
+            \r
+            uint32_t sr;\r
+            \r
+            while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & MC_FLASH_STATUS_READY))\r
                 ;\r
+            if(sr & (MC_FLASH_STATUS_LOCKE | MC_FLASH_STATUS_PROGE)) { \r
+                   dont_ack = 1;\r
+                    c->cmd = CMD_NACK;\r
+                    UsbSendPacket(packet, len);\r
+            }\r
             break;\r
 \r
         case CMD_HARDWARE_RESET:\r
             USB_D_PLUS_PULLUP_OFF();\r
-            RSTC_CONTROL = RST_CONTROL_KEY | RST_CONTROL_PROCESSOR_RESET;\r
+            AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;\r
             break;\r
-        \r
+\r
         case CMD_START_FLASH:\r
-            if(c->ext3 == START_FLASH_MAGIC) bootrom_unlocked = 1;\r
+            if(c->arg[2] == START_FLASH_MAGIC) bootrom_unlocked = 1;\r
             else bootrom_unlocked = 0;\r
             {\r
                 int prot_start = (int)&_bootrom_start;\r
                 int prot_end = (int)&_bootrom_end;\r
                 int allow_start = (int)&_flash_start;\r
                 int allow_end = (int)&_flash_end;\r
-                int cmd_start = c->ext1;\r
-                int cmd_end = c->ext2;\r
-                \r
+                int cmd_start = c->arg[0];\r
+                int cmd_end = c->arg[1];\r
+\r
                 /* Only allow command if the bootrom is unlocked, or the parameters are outside of the protected\r
-                 * bootrom area. In any case they must be within the flash area.
+                 * bootrom area. In any case they must be within the flash area.\r
                  */\r
                 if( (bootrom_unlocked || ((cmd_start >= prot_end) || (cmd_end < prot_start)))\r
                     && (cmd_start >= allow_start) && (cmd_end <= allow_end) ) {\r
@@ -148,7 +160,7 @@ void UsbPacketReceived(BYTE *packet, int len)
                 }\r
             }\r
             break;\r
-        \r
+\r
         default:\r
             Fatal();\r
             break;\r
@@ -165,18 +177,18 @@ static void flash_mode(int externally_entered)
        start_addr = 0;\r
        end_addr = 0;\r
        bootrom_unlocked = 0;\r
-       \r
+\r
        UsbStart();\r
        for(;;) {\r
                WDT_HIT();\r
-               \r
+\r
                UsbPoll(TRUE);\r
-               \r
+\r
                if(!externally_entered && !BUTTON_PRESS()) {\r
                        /* Perform a reset to leave flash mode */\r
                        USB_D_PLUS_PULLUP_OFF();\r
                        LED_B_ON();\r
-                       RSTC_CONTROL = RST_CONTROL_KEY | RST_CONTROL_PROCESSOR_RESET;\r
+                       AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;\r
                        for(;;);\r
                }\r
                if(externally_entered && BUTTON_PRESS()) {\r
@@ -195,65 +207,71 @@ void BootROM(void)
 \r
     // Kill all the pullups, especially the one on USB D+; leave them for\r
     // the unused pins, though.\r
-    PIO_NO_PULL_UP_ENABLE =     (1 << GPIO_USB_PU)          |\r
-                                (1 << GPIO_LED_A)           |\r
-                                (1 << GPIO_LED_B)           |\r
-                                (1 << GPIO_LED_C)           |\r
-                                (1 << GPIO_LED_D)           |\r
-                                (1 << GPIO_FPGA_DIN)        |\r
-                                (1 << GPIO_FPGA_DOUT)       |\r
-                                (1 << GPIO_FPGA_CCLK)       |\r
-                                (1 << GPIO_FPGA_NINIT)      |\r
-                                (1 << GPIO_FPGA_NPROGRAM)   |\r
-                                (1 << GPIO_FPGA_DONE)       |\r
-                                (1 << GPIO_MUXSEL_HIPKD)    |\r
-                                (1 << GPIO_MUXSEL_HIRAW)    |\r
-                                (1 << GPIO_MUXSEL_LOPKD)    |\r
-                                (1 << GPIO_MUXSEL_LORAW)    |\r
-                                (1 << GPIO_RELAY)              |\r
-                                (1 << GPIO_NVDD_ON);\r
-                                // (and add GPIO_FPGA_ON)\r
+    AT91C_BASE_PIOA->PIO_PPUDR =\r
+       GPIO_USB_PU                     |\r
+               GPIO_LED_A                      |\r
+               GPIO_LED_B                      |\r
+               GPIO_LED_C                      |\r
+               GPIO_LED_D                      |\r
+               GPIO_FPGA_DIN           |\r
+               GPIO_FPGA_DOUT          |\r
+               GPIO_FPGA_CCLK          |\r
+               GPIO_FPGA_NINIT         |\r
+               GPIO_FPGA_NPROGRAM      |\r
+               GPIO_FPGA_DONE          |\r
+               GPIO_MUXSEL_HIPKD       |\r
+               GPIO_MUXSEL_HIRAW       |\r
+               GPIO_MUXSEL_LOPKD       |\r
+               GPIO_MUXSEL_LORAW       |\r
+               GPIO_RELAY                      |\r
+               GPIO_NVDD_ON;\r
+               // (and add GPIO_FPGA_ON)\r
        // These pins are outputs\r
-    PIO_OUTPUT_ENABLE =         (1 << GPIO_LED_A)           |\r
-                                (1 << GPIO_LED_B)           |\r
-                                (1 << GPIO_LED_C)           |\r
-                                (1 << GPIO_LED_D)           |\r
-                                (1 << GPIO_RELAY)              |\r
-                                (1 << GPIO_NVDD_ON);\r
+    AT91C_BASE_PIOA->PIO_OER =\r
+       GPIO_LED_A                      |\r
+               GPIO_LED_B                      |\r
+               GPIO_LED_C                      |\r
+               GPIO_LED_D                      |\r
+               GPIO_RELAY                      |\r
+               GPIO_NVDD_ON;\r
        // PIO controls the following pins\r
-    PIO_ENABLE =                (1 << GPIO_USB_PU)          |\r
-                                (1 << GPIO_LED_A)           |\r
-                                (1 << GPIO_LED_B)           |\r
-                                (1 << GPIO_LED_C)           |\r
-                                (1 << GPIO_LED_D);\r
+    AT91C_BASE_PIOA->PIO_PER =\r
+       GPIO_USB_PU                     |\r
+               GPIO_LED_A                      |\r
+               GPIO_LED_B                      |\r
+               GPIO_LED_C                      |\r
+               GPIO_LED_D;\r
 \r
     USB_D_PLUS_PULLUP_OFF();\r
     LED_D_OFF();\r
     LED_C_ON();\r
     LED_B_OFF();\r
     LED_A_OFF();\r
-    \r
+\r
     // if 512K FLASH part - TODO make some defines :)\r
-    if ((DBGU_CIDR | 0xf00) == 0xa00) {\r
-           MC_FLASH_MODE0 = MC_FLASH_MODE_FLASH_WAIT_STATES(1) |\r
-           MC_FLASH_MODE_MASTER_CLK_IN_MHZ(0x48);\r
-           MC_FLASH_MODE1 = MC_FLASH_MODE_FLASH_WAIT_STATES(1) |\r
-           MC_FLASH_MODE_MASTER_CLK_IN_MHZ(0x48);\r
+    if ((AT91C_BASE_DBGU->DBGU_CIDR | 0xf00) == 0xa00) {\r
+           AT91C_BASE_EFC0->EFC_FMR =\r
+               MC_FLASH_MODE_FLASH_WAIT_STATES(1) |\r
+                       MC_FLASH_MODE_MASTER_CLK_IN_MHZ(0x48);\r
+           AT91C_BASE_EFC1->EFC_FMR =\r
+               MC_FLASH_MODE_FLASH_WAIT_STATES(1) |\r
+                       MC_FLASH_MODE_MASTER_CLK_IN_MHZ(0x48);\r
     } else {\r
-           MC_FLASH_MODE0 = MC_FLASH_MODE_FLASH_WAIT_STATES(0) |\r
-           MC_FLASH_MODE_MASTER_CLK_IN_MHZ(48);\r
+           AT91C_BASE_EFC0->EFC_FMR =\r
+               MC_FLASH_MODE_FLASH_WAIT_STATES(0) |\r
+                       MC_FLASH_MODE_MASTER_CLK_IN_MHZ(48);\r
     }\r
-    \r
+\r
     // Initialize all system clocks\r
     ConfigClocks();\r
-    \r
+\r
     LED_A_ON();\r
-    \r
+\r
     int common_area_present = 0;\r
-    switch(RSTC_STATUS & RST_STATUS_TYPE_MASK) {\r
-    case RST_STATUS_TYPE_WATCHDOG:\r
-    case RST_STATUS_TYPE_SOFTWARE:\r
-    case RST_STATUS_TYPE_USER:\r
+    switch(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_RSTTYP) {\r
+    case AT91C_RSTC_RSTTYP_WATCHDOG:\r
+    case AT91C_RSTC_RSTTYP_SOFTWARE:\r
+    case AT91C_RSTC_RSTTYP_USER:\r
            /* In these cases the common_area in RAM should be ok, retain it if it's there */\r
            if(common_area.magic == COMMON_AREA_MAGIC && common_area.version == 1) {\r
                    common_area_present = 1;\r
@@ -262,7 +280,7 @@ void BootROM(void)
     default: /* Otherwise, initialize it from scratch */\r
            break;\r
     }\r
-    \r
+\r
     if(!common_area_present){\r
            /* Common area not ok, initialize it */\r
            int i; for(i=0; i<sizeof(common_area); i++) { /* Makeshift memset, no need to drag util.c into this */\r
@@ -272,13 +290,15 @@ void BootROM(void)
            common_area.version = 1;\r
            common_area.flags.bootrom_present = 1;\r
     }\r
-    \r
+\r
     common_area.flags.bootrom_present = 1;\r
     if(common_area.command == COMMON_AREA_COMMAND_ENTER_FLASH_MODE) {\r
            common_area.command = COMMON_AREA_COMMAND_NONE;\r
            flash_mode(1);\r
     } else if(BUTTON_PRESS()) {\r
            flash_mode(0);\r
+    } else if(*(uint32_t*)&_osimage_entry == 0xffffffffU) {\r
+           flash_mode(1);\r
     } else {\r
            // jump to Flash address of the osimage entry point (LSBit set for thumb mode)\r
            asm("bx %0\n" : : "r" ( ((int)&_osimage_entry) | 0x1 ) );\r
Impressum, Datenschutz