/*## (c) SECURITY EXPLORATIONS    2018 poland                                #*/
/*##     http://www.security-explorations.com                                #*/

/* THIS SOFTWARE IS PROTECTED BY DOMESTIC AND INTERNATIONAL COPYRIGHT LAWS    */
/* UNAUTHORISED COPYING OF THIS SOFTWARE IN EITHER SOURCE OR BINARY FORM IS   */
/* EXPRESSLY FORBIDDEN. ANY USE, INCLUDING THE REPRODUCTION, MODIFICATION,    */
/* DISTRIBUTION, TRANSMISSION, RE-PUBLICATION, STORAGE OR DISPLAY OF ANY      */
/* PART OF THE SOFTWARE, FOR COMMERCIAL OR ANY OTHER PURPOSES REQUIRES A      */
/* VALID LICENSE FROM THE COPYRIGHT HOLDER.                                   */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    */
/* SECURITY EXPLORATIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF  */
/* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                                  */

import java.lang.*;

public class STSecFuses {
 public static final String fuses[][]={
  {"jtag_protect",              "fe00d000", "4",   "c"},
  {"engineering_test_000",      "fe00d028", "1",   "6"},
  {"trans_cw_secure",           "fe00d03c", "1",   "1"},
  {"trans_cw_enable",           "fe00d02C", "1",   "5"},
  {"crypt_cpu0_ifetch_src_rst", "fe00d040", "1",   "2"},
  {"crypt_cpu1_ifetch_src_rst", "fe00d040", "1",   "3"},  
  {"crypt_cpu2_ifetch_src_rst", "fe00d040", "1",   "4"},
  {"crypt_sigdma_src_rst",      "fe00d040", "1",   "6"},  
  {"crypt_sigchk_src_rst",      "fe00d040", "1",   "7"},
  {"crypt_watchdog_src_rst",    "fe00d040", "1",   "8"},
  {"crypt_hash_include_addr",   "fe00d040", "1",   "9"},
  {"crypt_sigchk_enable",       "fe00d040", "1",   "a"},
  {"mes0_enable",               "fe00d048", "1",   "0"},
  {"mes0_src_id_mon_enable",    "fe00d048", "1",   "1"},
  {"mes0_encrypt_all_enable",   "fe00d048", "1",   "2"},
  {"t1_filter_enable",          "fe00d048", "1",   "d"},
  {"dirt_disable",              "fe00d048", "1",   "f"},
  {"engineering_0",             "fe00d04c", "10",  "0"},
  {"engineering_1",             "fe00d050", "10",  "0"},
  {"engineering_2",             "fe00d054", "10",  "0"},
  {"engineering_3",             "fe00d058", "10",  "0"},
  {"metal_fix_nb",              "fe00d05c", "4",   "0"},
  {"proc_type",                 "fe00d05c", "3",   "4"},
  {"fab_loc",                   "fe00d05c", "5",   "7"},
  {"customer_otp0",             "fe00d068", "10",  "0"},
  {"customer_otp1",             "fe00d06c", "10",  "0"},
  {"customer_otp2",             "fe00d070", "10",  "0"},
  {"customer_otp3",             "fe00d074", "10",  "0"},
  {"soc_public_id",             "fe00d080", "40",  "0"},
  {"crypt_stc",                 "fe00d088", "20",  "0"},
  {"full_sales_type",           "fe00d08c", "20",  "0"},
  {"gp_bulk128_0",              "fe00d0e0", "80",  "0"},
  {"gp_bulk128_1",              "fe00d0f0", "80",  "0"},
  {"bulk_otp",                  "fe00d100", "800", "0"},
  {"pci_disable",               "fe00d044", "1",   "d"}
 };

 public static final int PAD = 30;

 private static int mask(int numbits) {
  int mask=0;

  for(int i=0;i<numbits;i++) {
   mask<<=1;
   mask|=0x01;
  }

  return mask;
 }

 public static int get_value(int addr,int mask,int shift) {
  int val=STTKDMA.iomem_read(addr);

  return (val>>shift)&mask;
 }

 public static void print() throws Throwable {
  for(int i=0;i<fuses.length;i++) {
   String config[]=(String[])fuses[i];

   String name=config[0];
   String saddr=config[1];
   String smaskbits=config[2];
   String sshift=config[3];

   int addr=(int)Long.parseLong(saddr,16);
   int maskbits=Integer.parseInt(smaskbits,16);
   int shift=Integer.parseInt(sshift,16);

   if (maskbits<=0x20) {   
    int mask=mask(maskbits);

    int val=get_value(addr,mask,shift);
    
    String s=Utils.padded_string("@"+name,PAD)+"0x"+Utils.hex_value(val,8);
    Output.text(s);
   } else {
    int len=maskbits>>3;

    int ptr=NativeCode.getInstance().malloc(len);

    for(int j=0;j<len;j+=4) {
     int val=STTKDMA.iomem_read(addr+j);
     Memory.write_dword(ptr+j,val);
    }

    String s=Utils.padded_string("@"+name,PAD);
    Output.text(s);

    byte buf[]=Utils.buf2barray(ptr,len);
    MPEG.print_buf(2,buf);
   }
  }
 }
}
