/*                                             -*- mode:C++; fill-column:100 -*-
 * SFBProvenanceData.h - The actual program description block itself,
 *                       compiled anew on every build
 * Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.
 *
 * This file is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 * USA
 */

/**
  \file  SFBProvenanceData.h - The actual program description block itself,
         compiled anew on every build
  \author David H. Ackley.  
  \date (C) 2009 All rights reserved.
  \lgpl
 */

/*
 * NOTE: This file, even though it is a .h, includes variable
 * _definitions_, not just declarations.  That is because this file,
 * when used, MUST BE INCLUDED DURING ONLY ONE COMPILATION STEP!
 *
 * For sketches, this file is expected to be included only during the
 * compilation of 'sketch-wrapper.cpp'.
 *
 * It is the date and time of _that one compilation step_ that
 * determines the buildDate and buildTime in 'theProvenance'.  This
 * file and the sketch loader script together conspire to place
 * 'theProvenance' at the very beginning of the compiled image.
 */


#ifndef SFBPROVENANCEDATA_H
#define SFBPROVENANCEDATA_H

#include "SFBProvenance.h"

#ifndef HOST_MODE
#define IN_HEADER  __attribute__((section (".header")))
#define IN_FOOTER  __attribute__((section (".footer")))
#else
#define IN_HEADER  /* nothing */
#define IN_FOOTER  /* nothing */
#endif

#ifndef SFB_SKETCH_CREATOR_ID
#define SFB_SKETCH_CREATOR_ID (0)
#endif

#ifndef SFB_SKETCH_PROGRAM_ID
#define SFB_SKETCH_PROGRAM_ID (0)
#endif

#ifndef SFB_SKETCH_COPYRIGHT_NOTICE
#define SFB_SKETCH_COPYRIGHT_NOTICE (0)
#endif

u32 theFooter IN_FOOTER = SFB_PROVENANCE_NZTRX;  // loader script puts .footer section after everything else.

extern char __rom_length;       // Provided by sfbloader.ld

volatile const SFBProvenance theProvenance IN_HEADER  = {  // Yow, it really must be volatile const!
  0xEA000000+sizeof(SFBProvenance)/4-2, // ARM Branch instruction, offset is blocksize (in words) less 2 for pipeline
  0,                            // checksum0
  0,                            // checksum1
  0,                            // sourceOwnerId
  0,                            // sourceBoardId
  SFB_PROVENANCE_MAGIC,
  0,                            // flags (TBD)
  0,                            // reserved (TBD)
  SKETCH_ARCH_CODE,             // set by compilation flags
  SFB_SKETCH_CREATOR_ID,         
  SFB_SKETCH_PROGRAM_ID,
  SKETCH_BUILD_DATE,
  SKETCH_BUILD_TIME,
  (int) &__rom_length,
  (u32) SFB_SKETCH_COPYRIGHT_NOTICE,
  SFB_PROVENANCE_CIGAM
};

extern void initProgramServerSketch() {
  programServerSetSketch(&theProvenance,(uptr) &theProvenance, 0);
}

/**
 * 0 if we want the code
 * <0 if packet is not a valid 'Ph' format
 * >0 if packet is a valid 'Ph' but we don't want what it offers
 */
int wantPhPacketCodeUpdate(u8 * packet) {
  if (!packet)
    return -1;

  u8 arch;
  int cid, pid, bdt, btm;
  u32 matches = 
    packetScanf(packet,"Ph%c%l%l%l%l%\n", &arch, &cid, &pid, &bdt, &btm);
  if (matches < 8) return -(matches+2);
  if (cid == -1 || pid == -1) return -10;
  if (bdt < 0 || btm < 0) return -11;
  if (arch != SKETCH_ARCH_CODE) return -(400+10*arch+SKETCH_ARCH_CODE);

  u8 bootMode = getBootBlockBootMode();

  if (bootMode!=GREEN_BOOT_MODE && cid != theProvenance.creatorId) return 1;
  if (bootMode!=GREEN_BOOT_MODE && pid != theProvenance.programId) return 2;
  if (bdt < theProvenance.buildDate) return 3;
  if (bdt == theProvenance.buildDate && btm < theProvenance.buildTime) return 4;
  if (bdt == theProvenance.buildDate && btm == theProvenance.buildTime) return 5;

  return 0;
}



#endif /* SFBPROVENANCEDATA_H */

