root/loader/generic/check_compat.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_led
  2. get_pid
  3. blink
  4. ver_cmp
  5. check_pid
  6. check_compat
  7. core_copy

   1 /* This file should be used in loader for boot compatibility checks */
   2 
   3 #ifndef OPT_DISABLE_COMPAT_CHECK
   4 
   5 typedef struct {
   6     short *fw_pid;
   7     short pid;
   8 } pid_sig_t;
   9 
  10 typedef struct {
  11     const char *fw_str;
  12     const char *str;
  13 } ver_sig_t;
  14 
  15 /*
  16 Any changes to the following struct have to be reflected in the tools/compatbuilder.sh script
  17 */
  18 typedef struct {
  19     unsigned short pid;     // camera P-ID
  20     short method;           // LED control method (BLINK_LED_CONTROL= in platform/(cam)/makefile.inc)
  21     unsigned int led;       // LED MMIO address (BLINK_LED_GPIO= in platform/(cam)/makefile.inc)
  22     unsigned int addr;      // location of P-ID
  23 } pid_led_t;
  24 
  25 /*
  26 LED control methods
  27 */
  28 #define LEDCNTRL_UNK  0     // LED control unknown (no blink possible)
  29 #define LEDCNTRL_OLD  1     // DIGIC II...4; 0x46 to on, 0x44 to off
  30 #define LEDCNTRL_NEW1 2     // DIGIC 5; bit5, inverted
  31 #define LEDCNTRL_NEW2 3     // DIGIC 4+, 5; 0x93d800 to on, 0x83dc00 to off
  32 #define LEDCNTRL_NEW3 4     // DIGIC 6; 0x4d0002 to on, 0x4c0003 to off
  33 
  34 #ifndef NEED_ENCODED_DISKBOOT
  35 #define NEED_ENCODED_DISKBOOT 0
  36 #endif
  37 
  38 // following must be ordered by P-ID, order to be maintained inside NEED_ENCODED_DISKBOOT blocks only
  39 pid_led_t pid_leds[]={
  40 // insert generated data
  41 #include "compat_table.h"
  42 };
  43 
  44 // compatibility definitions from platform/sub
  45 #include "bin_compat.h"
  46 
  47 #ifndef DEBUG_DELAY
  48     #define DEBUG_DELAY 10000000
  49 #endif
  50 
  51 void set_led(int led, int state, int method) {
  52     volatile long *p = (void*)led;
  53 
  54     if (method == LEDCNTRL_NEW1) {
  55         // DIGIC 5
  56         *p = (*p & 0xFFFFFFCF) | ((state) ? 0x00 : 0x20);
  57     }
  58     else if (method == LEDCNTRL_NEW2) {
  59         // DIGIC 4+, 5
  60         *p = ((state) ? 0x93d800 : 0x83dc00);
  61     }
  62     else if (method == LEDCNTRL_NEW3) {
  63         // DIGIC 6
  64         *p = ((state) ? 0x4d0002 : 0x4c0003);
  65     }
  66     else if (method == LEDCNTRL_OLD) {
  67         *p = ((state) ? 0x46 : 0x44);
  68     }
  69 }
  70 
  71 const int num_pid_sigs = sizeof(pid_sigs)/sizeof(pid_sig_t);
  72 const int num_ver_sigs = sizeof(ver_sigs)/sizeof(ver_sig_t);
  73 const int led_addresses = sizeof(pid_leds)/sizeof(pid_led_t);
  74 
  75 unsigned short get_pid(void) {
  76     int i;
  77     for(i=0;i<led_addresses;i++) {
  78         if( (*(unsigned short*)pid_leds[i].addr >= pid_leds[0].pid) &&
  79             (*(unsigned short*)pid_leds[i].addr <= pid_leds[led_addresses-1].pid) ) {
  80             // return the first possible number which looks like a valid P-ID
  81             return *(unsigned short*)pid_leds[i].addr;
  82         }
  83     }
  84     return 0;
  85 }
  86 
  87 void blink(unsigned short cam_pid) {
  88     unsigned int led = 0;
  89     int method = LEDCNTRL_UNK;
  90     int i;
  91     // check if there's a known LED
  92     for(i=0;i<led_addresses;i++) {
  93         if(cam_pid == pid_leds[i].pid) {
  94             led = pid_leds[i].led;
  95             method = pid_leds[i].method;
  96             break;
  97         }
  98     }
  99     // no known LED, no blink
 100     if (!led)
 101         while(1);
 102     // LED found, blink (control method chosen according to the type of GPIO)
 103     while(1) {
 104         set_led(led, 1, method);
 105         for(i=0;i<DEBUG_DELAY;i++) {
 106             asm("nop\n nop\n");
 107         };
 108         set_led(led, 0, method);
 109         for(i=0;i<DEBUG_DELAY;i++) {
 110             asm("nop\n nop\n");
 111         };
 112     }
 113 }
 114 
 115 // my_ver assumed to be a null terminated string like 1.00A
 116 int ver_cmp(const char *my_ver, const char *fw_ver) {
 117     int i=0;
 118     while(my_ver[i] == fw_ver[i] && my_ver[i] != 0)
 119         i++;
 120     return my_ver[i] == 0; // hit the null in our string
 121 }
 122 
 123 unsigned short check_pid(void) {
 124     int i;
 125     // skip check if pid information not available
 126     if (num_pid_sigs == 0)
 127         return 0;
 128     for(i=0;i<num_pid_sigs;i++) {
 129         if(*pid_sigs[i].fw_pid == pid_sigs[i].pid) {
 130             return pid_sigs[i].pid;
 131         }
 132     }
 133     i = get_pid();
 134     blink(i);
 135     return 0; // to make the compiler happy
 136 }
 137 
 138 #endif // OPT_DISABLE_COMPAT_CHECK
 139 
 140 void check_compat(void) {
 141 #ifndef OPT_DISABLE_COMPAT_CHECK
 142     int i;
 143     unsigned short cam_pid;
 144     cam_pid = check_pid();
 145     for(i=0;i<num_ver_sigs;i++) {
 146         if(ver_cmp(ver_sigs[i].str,ver_sigs[i].fw_str)) {
 147             return;
 148        }
 149     }
 150     blink(cam_pid);
 151 #endif
 152 }
 153 
 154 void core_copy(const long *src, long *dst, long length) {
 155     if (src < dst && dst < src + length) {
 156         /* Have to copy backwards */
 157         src += length;
 158         dst += length;
 159         while (length--)  *--dst = *--src;
 160     }
 161     else
 162         while (length--)  *dst++ = *src++;
 163 }
 164 

/* [<][>][^][v][top][bottom][index][help] */