/* * Miscellaneous process/domain related routines * * Copyright (C) 2004 Hewlett-Packard Co. * Dan Magenheimer (dan.magenheimer@hp.com) * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern void die_if_kernel(char *str, struct pt_regs *regs, long err); /* FIXME: where these declarations shold be there ? */ extern int ia64_hyperprivop(unsigned long, REGS *); extern IA64FAULT ia64_hypercall(struct pt_regs *regs); #define IA64_PSR_CPL1 (__IA64_UL(1) << IA64_PSR_CPL1_BIT) // note IA64_PSR_PK removed from following, why is this necessary? #define DELIVER_PSR_SET (IA64_PSR_IC | IA64_PSR_I | \ IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_CPL1 | \ IA64_PSR_IT | IA64_PSR_BN) #define DELIVER_PSR_CLR (IA64_PSR_AC | IA64_PSR_DFL | IA64_PSR_DFH | \ IA64_PSR_SP | IA64_PSR_DI | IA64_PSR_SI | \ IA64_PSR_DB | IA64_PSR_LP | IA64_PSR_TB | \ IA64_PSR_CPL | IA64_PSR_MC | IA64_PSR_IS | \ IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | \ IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | IA64_PSR_IA) extern void do_ssc(unsigned long ssc, struct pt_regs *regs); // should never panic domain... if it does, stack may have been overrun void check_bad_nested_interruption(unsigned long isr, struct pt_regs *regs, unsigned long vector) { struct vcpu *v = current; if (!(PSCB(v,ipsr) & IA64_PSR_DT)) { panic_domain(regs,"psr.dt off, trying to deliver nested dtlb!\n"); } vector &= ~0xf; if (vector != IA64_DATA_TLB_VECTOR && vector != IA64_ALT_DATA_TLB_VECTOR && vector != IA64_VHPT_TRANS_VECTOR) { panic_domain(regs,"psr.ic off, delivering fault=%lx,ipsr=%lx,iip=%lx,ifa=%lx,isr=%lx,PSCB.iip=%lx\n", vector,regs->cr_ipsr,regs->cr_iip,PSCB(v,ifa),isr,PSCB(v,iip)); } } void reflect_interruption(unsigned long isr, struct pt_regs *regs, unsigned long vector) { struct vcpu *v = current; if (!PSCB(v,interrupt_collection_enabled)) check_bad_nested_interruption(isr,regs,vector); PSCB(v,unat) = regs->ar_unat; // not sure if this is really needed? PSCB(v,precover_ifs) = regs->cr_ifs; vcpu_bsw0(v); PSCB(v,ipsr) = vcpu_get_ipsr_int_state(v,regs->cr_ipsr); PSCB(v,isr) = isr; PSCB(v,iip) = regs->cr_iip; PSCB(v,ifs) = 0; PSCB(v,incomplete_regframe) = 0; regs->cr_iip = ((unsigned long) PSCBX(v,iva) + vector) & ~0xffUL; regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; regs->r31 = current->domain->arch.shared_info_va + XSI_IPSR_OFS; v->vcpu_info->evtchn_upcall_mask = 1; PSCB(v,interrupt_collection_enabled) = 0; perfc_incra(slow_reflect, vector >> 8); } static unsigned long pending_false_positive = 0; void reflect_extint(struct pt_regs *regs) { unsigned long isr = regs->cr_ipsr & IA64_PSR_RI; struct vcpu *v = current; static int first_extint = 1; if (first_extint) { printf("Delivering first extint to domain: isr=0x%lx, iip=0x%lx\n", isr, regs->cr_iip); first_extint = 0; } if (vcpu_timer_pending_early(v)) printf("*#*#*#* about to deliver early timer to domain %d!!!\n",v->domain->domain_id); PSCB(current,itir) = 0; reflect_interruption(isr,regs,IA64_EXTINT_VECTOR); } void reflect_event(struct pt_regs *regs) { unsigned long isr = regs->cr_ipsr & IA64_PSR_RI; struct vcpu *v = current; /* Sanity check */ if (is_idle_vcpu(v) || !user_mode(regs)) { //printk("WARN: invocation to reflect_event in nested xen\n"); return; } if (!event_pending(v)) return; if (!PSCB(v,interrupt_collection_enabled)) printf("psr.ic off, delivering event, ipsr=%lx,iip=%lx,isr=%lx,viip=0x%lx\n", regs->cr_ipsr, regs->cr_iip, isr, PSCB(v, iip)); PSCB(v,unat) = regs->ar_unat; // not sure if this is really needed? PSCB(v,precover_ifs) = regs->cr_ifs; vcpu_bsw0(v); PSCB(v,ipsr) = vcpu_get_ipsr_int_state(v,regs->cr_ipsr); PSCB(v,isr) = isr; PSCB(v,iip) = regs->cr_iip; PSCB(v,ifs) = 0; PSCB(v,incomplete_regframe) = 0; regs->cr_iip = v->arch.event_callback_ip; regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; regs->r31 = current->domain->arch.shared_info_va + XSI_IPSR_OFS; v->vcpu_info->evtchn_upcall_mask = 1; PSCB(v,interrupt_collection_enabled) = 0; } // ONLY gets called from ia64_leave_kernel // ONLY call with interrupts disabled?? (else might miss one?) // NEVER successful if already reflecting a trap/fault because psr.i==0 void deliver_pending_interrupt(struct pt_regs *regs) { struct domain *d = current->domain; struct vcpu *v = current; // FIXME: Will this work properly if doing an RFI??? if (!is_idle_domain(d) && user_mode(regs)) { if (vcpu_deliverable_interrupts(v)) reflect_extint(regs); else if (PSCB(v,pending_interruption)) ++pending_false_positive; } } static int handle_lazy_cover(struct vcpu *v, struct pt_regs *regs) { if (!PSCB(v,interrupt_collection_enabled)) { PSCB(v,ifs) = regs->cr_ifs; PSCB(v,incomplete_regframe) = 1; regs->cr_ifs = 0; perfc_incrc(lazy_cover); return(1); // retry same instruction with cr.ifs off } return(0); } void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs, unsigned long itir) { unsigned long iip = regs->cr_iip, iha; // FIXME should validate address here unsigned long pteval; unsigned long is_data = !((isr >> IA64_ISR_X_BIT) & 1UL); IA64FAULT fault; int is_ptc_l_needed = 0; u64 logps; if ((isr & IA64_ISR_SP) || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) { /* * This fault was due to a speculative load or lfetch.fault, set the "ed" * bit in the psr to ensure forward progress. (Target register will get a * NaT for ld.s, lfetch will be canceled.) */ ia64_psr(regs)->ed = 1; return; } again: fault = vcpu_translate(current,address,is_data,&pteval,&itir,&iha); if (fault == IA64_NO_FAULT || fault == IA64_USE_TLB) { struct p2m_entry entry; pteval = translate_domain_pte(pteval, address, itir, &logps, &entry); vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,logps); if ((fault == IA64_USE_TLB && !current->arch.dtlb.pte.p) || p2m_entry_retry(&entry)) { /* dtlb has been purged in-between. This dtlb was matching. Undo the work. */ vcpu_flush_tlb_vhpt_range(address, logps); // the stale entry which we inserted above // may remains in tlb cache. // we don't purge it now hoping next itc purges it. is_ptc_l_needed = 1; goto again; } return; } if (is_ptc_l_needed) vcpu_ptc_l(current, address, logps); if (!user_mode (regs)) { /* The fault occurs inside Xen. */ if (!ia64_done_with_exception(regs)) { // should never happen. If it does, region 0 addr may // indicate a bad xen pointer printk("*** xen_handle_domain_access: exception table" " lookup failed, iip=0x%lx, addr=0x%lx, spinning...\n", iip, address); panic_domain(regs,"*** xen_handle_domain_access: exception table" " lookup failed, iip=0x%lx, addr=0x%lx, spinning...\n", iip, address); } return; } if ((isr & IA64_ISR_IR) && handle_lazy_cover(current, regs)) return; if (!PSCB(current,interrupt_collection_enabled)) { check_bad_nested_interruption(isr,regs,fault); //printf("Delivering NESTED DATA TLB fault\n"); fault = IA64_DATA_NESTED_TLB_VECTOR; regs->cr_iip = ((unsigned long) PSCBX(current,iva) + fault) & ~0xffUL; regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; // NOTE: nested trap must NOT pass PSCB address //regs->r31 = (unsigned long) &PSCB(current); perfc_incra(slow_reflect, fault >> 8); return; } PSCB(current,itir) = itir; PSCB(current,iha) = iha; PSCB(current,ifa) = address; reflect_interruption(isr, regs, fault); } fpswa_interface_t *fpswa_interface = 0; void trap_init (void) { if (ia64_boot_param->fpswa) /* FPSWA fixup: make the interface pointer a virtual address: */ fpswa_interface = __va(ia64_boot_param->fpswa); else printk("No FPSWA supported.\n"); } static fpswa_ret_t fp_emulate (int fp_fault, void *bundle, unsigned long *ipsr, unsigned long *fpsr, unsigned long *isr, unsigned long *pr, unsigned long *ifs, struct pt_regs *regs) { fp_state_t fp_state; fpswa_ret_t ret; if (!fpswa_interface) return ((fpswa_ret_t) {-1, 0, 0, 0}); memset(&fp_state, 0, sizeof(fp_state_t)); /* * compute fp_state. only FP registers f6 - f11 are used by the * kernel, so set those bits in the mask and set the
/* **************************************************************************

   This program creates a CRC checksum and encodes the file that is named
   in the command line.
   
   Compile with:  gcc encode_crc.c -Wall -o encode_crc

   Author:     Michael Margraf  (michael.margraf@freecom.com)
   Copyright:  Freecom Technology GmbH, Berlin, 2004
               www.freecom.com

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program 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
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

 ************************************************************************* */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

// *******************************************************************
// CCITT polynom G(x)=x^16+x^12+x^5+1
#define POLYNOM  0x1021

// CRC algorithm with MSB first
int make_crc16(int crc, char new)
{
  int i;
  crc = crc ^ (((int)new) << 8);
  
  for(i=0; i<8; i++) {  // work on 8 bits in "new"
    crc <<= 1;          // MSBs first
    if(crc & 0x10000)  crc ^= POLYNOM;
  }
  return crc & 0xFFFF;
}

// *******************************************************************
// Reads the file "filename" into memory and returns pointer to the buffer.
static char *readfile(char *filename, int *size)
{
	FILE		*fp;
	char		*buffer;
	struct stat	info;
	
	if (stat(filename,&info)!=0)
		return NULL;

	if ((fp=fopen(filename,"r"))==NULL)
		return NULL;

	buffer=NULL;
	for (;;)
	{
		if ((buffer=(char *)malloc(info.st_size+1))==NULL)
			break;

		if (fread(buffer,1,info.st_size,fp)!=info.st_size)
		{
			free(buffer);
			buffer=NULL;
			break;
		}

		buffer[info.st_size]='\0';
		if(size) *size = info.st_size;

		break;
	}

	(void)fclose(fp);

	return buffer;
}


// *******************************************************************
int main(int argc, char** argv)
{
  if(argc < 3) {
    printf("ERROR: Argument missing!\n\n");
    return 1;
  }

  int count;  // size of file in bytes
  char *p, *master = readfile(argv[1], &count);
  if(!master) {
    printf("ERROR: File not found!\n");
    return 1;
  }

  int crc = 0xFFFF, z;

  p = master;
  for(z=0; z<count; z++)
    crc = make_crc16(crc, *(p++));  // calculate CRC
  short crc16 = (short)crc;

	/*
  if(argc > 2) {   // with flag for device recognition ?
    p = argv[2];
    for(z=strlen(p); z>0; z--) {
      crc ^= (int)(*p);
      *(p++) = (char)crc;  // encode device flag
    }
  }
	*/

  p = master;
  for(z=0; z<count; z++) {
    crc ^= (int)(*p);
    *(p++) = (char)crc;  // encode file
  }


  // write encoded file...
  FILE *fp = fopen(argv[2], "w");
  if(!fp) {
    printf("ERROR: File not writeable!\n");
    return 1;
  }

  if(argc > 3) {  // add flag for device recognition ?
    fwrite(argv[3], strlen(argv[3]), sizeof(char), fp);
  }
  else {
    // Device is an FSG, so byte swap (IXP4xx is big endian)
    crc16 = ((crc16 >> 8) & 0xFF) | ((crc16 << 8) & 0xFF00);
  }

  fwrite(&crc16, 1, sizeof(short), fp);     // first write CRC

  fwrite(master, count, sizeof(char), fp);  // write content
  fclose(fp);

  free(master);
  return 0;
}