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

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