/**************************************************************************** * sec2_init.c -- The Initialization code for SEC2 Driver **************************************************************************** * Copyright (c) Certicom Corp. 1996-2002. All rights reserved * Copyright (c) 2003-2005 Freescale Semiconductor * All Rights Reserved. Proprietary and Confidential. * * NOTICE: The information contained in this file is proprietary * to Freescale Semiconductor, and is being made available to * Freescale's customers under strict license agreements. * Use or disclosure of this information is permissible only * under the terms of the existing license agreement. ***************************************************************************/ /* Revision History: * 1.0 Aug 24,2003 dgs - adapted from the final version of mpc18x * 1.1.0 Nov 16,2004 sec - incorporate linux changes from prior versions * 1.1.1 Dec 16,2004 sec - remove old unused diagnostics * 1.2 Jan 27,2005 sec - fix comments associated with global inhibit */ #define SEC2_GLOBAL #define INIT_C #include "Sec2Driver.h" /* Interpeak begin */ #undef NUM_CHANNELS #define NUM_CHANNELS (num_channels) int num_channels; extern int ipfreescale_sec_num_channels(void); /* Interpeak end */ #if defined(DBG) /* unsigned long SEC2DebugLevel = (DBGTXT_SETRQ | DBGTXT_SVCRQ | DBGTXT_INITDEV | DBGTXT_DPDSHOW | DBGTXT_INFO); */ unsigned long SEC2DebugLevel = (DBGTXT_INFO); #else unsigned long SEC2DebugLevel = 0x0; #endif #ifdef __KERNEL EXPORT_SYMBOL(SEC2DebugLevel); #endif /************************************************************************* * Function Name: SEC2DriverInit * Purpose: * Step1: Build base address by requesting peripheral base * Step2: Init ChannelRegister & Cha Register * Step3: Allocate Channel Assignments * Step4: Init ChannelAssignments & ChaAssignments * Step5: Init ProcessQueueTop & ProcessQueueBottom * Step6: Init Semaphores * Step7: Reset all Chas and Channels * Step8: Config all Channels * Step9: Connect Interrupt * Step10: Enable Interrupt * Step11: Return Success * * Input: None * * Return: SEC2_SUCCESS if everything passed, otherwise the error code *************************************************************************/ /* static unsigned long CurrentCHAStatus[2]; */ int SEC2DriverInit(void) { static int status, i; static int cha; static int channel; static unsigned long address; static unsigned int idx[] = {0,2,4,3,5,1}; static char *coreID; #ifdef __KERNEL__ bd_t *binfo = (bd_t *) __res; #endif /* Interpeak begin */ num_channels = ipfreescale_sec_num_channels(); /* Interpeak end */ /* Check prior initialization, and initialize driver per OS convention */ #ifdef VXWORKS if (taskIdVerify (taskNameToId ("tSEC2_pc")) == OK) { printf ("\nSecurity Processor already initialized\n"); return (OK); } #endif #ifdef __KERNEL__ /* Anything not done in the module init hook? */ #endif /* sysGetPeripheralBase() gets the PQ3 CCSBAR from the OS */ #ifdef VXWORKS IOBaseAddress = (sysGetPeripheralBase() + TALITOS2X_BASE_ADDRESS); #endif /* get base from the kernel, and map it into an accessible region */ #ifdef __KERNEL__ IOBaseAddress = (unsigned long) ioremap((phys_addr_t)(binfo->bi_immr_base + TALITOS2X_BASE_ADDRESS), SEC2_BASE_SIZE); #endif /* Identify the running hardware */ SEC2Dump(DBGTXT_INFO, ("SEC 2.x Security Processor Core\n")); SEC2Dump(DBGTXT_INFO, ("Driver Version %s %s %s\n", VERSION, __DATE__,__TIME__)); coremask = *((volatile unsigned long *)(IOBaseAddress + IDENTIFICATION_OFFSET) + 1); switch(coremask) { case SEC_COREID_2_0_0: coreID = "2.0.0"; break; case SEC_COREID_2_1_0: coreID = "2.1.0"; break; default: coreID = "unknown"; break; } SEC2Dump(DBGTXT_INFO, ("Security Core Version Mask: %s (0x%08lx)\n\n", coreID, coremask)); /* set up rebound cha index table */ memcpy ((char *)cha_idx, (char *)idx, sizeof (idx)); /* set up SEC2 register addresses */ /* controller registers */ ChaAssignmentStatusRegister = (volatile unsigned long*) (IOBaseAddress + CHA_ASSIGNMENT_STATUS_OFFSET); InterruptControlRegister = (volatile unsigned long*) (IOBaseAddress + INTERRUPT_CONTROL_OFFSET); InterruptStatusRegister = (volatile unsigned long*) (IOBaseAddress + INTERRUPT_STATUS_OFFSET); InterruptClearRegister = (volatile unsigned long*) (IOBaseAddress + INTERRUPT_CLEAR_OFFSET); IdRegister = (volatile unsigned long*) (IOBaseAddress + IDENTIFICATION_OFFSET); MasterControlRegister = (volatile unsigned long *) (IOBaseAddress + SEC2_MASTER_CONTROL_REGISTER); SEC2Dump(DBGTXT_INITDEV, ("SEC2DriverInit->IOBaseAddress=0x%08lx\n", IOBaseAddress)); /* Reset the SEC2 */ /* Note that we turn on global inhibit for all processors. At the time */ /* of coding, GI only exists in the 8349; it's irrelevant to PQ3 devices. */ /* So, it's just turned on for all processors, which is OK for now. */ /* In time, this may be need to become an option in build configuration. */ SEC2Dump(DBGTXT_INITDEV, ("SEC2DriverInit->reset Master Control Register\n")); *(MasterControlRegister) = SEC2_RESET | SEC2_GLOBAL_INHIBIT; *(MasterControlRegister + 1) = 0; SEC2Dump(DBGTXT_INITDEV, ("SEC2DriverInit->IdRegister=0x%08lx 0x%08lx\n", *(IdRegister), *(IdRegister + 1))); /* channel registers */ SEC2Dump(DBGTXT_INITDEV, ("SEC2DriverInit->channel registers\n")); for (channel=0, address=CHANNEL_CONFIG_BASE; channelcha registers\n")); for (cha=0,address=CHA_RESET_CONTROL_BASE; chaallocating other driver variables\n")); /* variable init */ FreeChannels = NUM_CHANNELS; FreeRngas = NUM_RNGAS; FreeAfhas = NUM_AFHAS; FreeDesas = NUM_DESAS; FreeMdhas = NUM_MDHAS; FreePkhas = NUM_PKHAS; FreeAesas = NUM_AESAS; /* Init ChannelAssignments */ for (channel=0; channelreset Reset Control Register %d\n", NUM_CHAS)); for (cha=0; chareset Crypto-Channel Configuration Registers %d\n", NUM_CHANNELS)); for (channel=0; channelenable interrupts\n")); /* Unmask all "done" bits from all channels and accelerators */ *(InterruptControlRegister) = ALL_CHANNEL_INT_DONE_MASK | ALL_CHANNEL_INT_ERROR_MASK; *(InterruptControlRegister + 1) = ALL_CHA_INT_ERROR_MASK; SEC2Dump(DBGTXT_INITDEV, ("SEC2DriverInit->return SEC2_SUCCESS!\n")); return SEC2_SUCCESS; } /* end of DriverEntry */ IO_STATUS InitChannelAssignment(int channel) { size_t count; SEC2Dump(DBGTXT_INITDEV, ("InitChannelAssignment channel=%d\n", channel+1)); ChannelAssignments[channel].assignment = CHANNEL_FREE; ChannelAssignments[channel].ownerTaskId = 0; ChannelAssignments[channel].pReq = NULL; ChannelAssignments[channel].pCurrReq = NULL; ChannelAssignments[channel].Dpds = &dpd[channel][0]; for (count=0; count