⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv.c

📁 MMI层OBJ不能完全编译
💻 C
📖 第 1 页 / 共 5 页
字号:
        // memory map the file and update block addresses of binfo array
#ifdef WIN32
        image_addr = MapViewOfFile( map_fd,
                                    FILE_MAP_ALL_ACCESS,
                                    0,
                                    0,
                                    0);
#else //WIN32
        image_addr = mmap(0, image_size, PROT_READ|PROT_WRITE,
                          MAP_FILE|MAP_SHARED, image_fd, 0);
#endif //WIN32
    }

    tw(tr(TR_END, TrDrvInit, "}\n"));

    return image_addr;
}

#endif // (TARGET == 0)


/******************************************************************************
 * Device Detection and Copying of Driver to RAM
 ******************************************************************************/

#if (TARGET == 1)

// Note that this function reads device code of any of the three known flash
// families; Intel, AMD and SST. This works because Intel and AMD use
// the same command data for entering READ_IDENTIFIER mode (0x90).
// The function should be copied and executed from RAM!
#if (CHIPSET != 15)
void ffsdrv_device_id_read(uint32 base_addr, uint16 *manufact, uint16 *device)
{
    int addr, i;

    // This silly looking code has one purpose; to set addr = 0xAAAA. It is
    // necessary in order to force the compiler NOT to produce code that
    // uses LDR opcode(s) with PC-relative addressing. The assember code
    // produced from this C code is completely relocatable!
    for (i = 0, addr = 0; i < 2; i++)
        addr |= addr << 8 | 0xAA;

    FLASH_WRITE_HALFWORD (base_addr + addr,        0xAA);
    FLASH_WRITE_HALFWORD (base_addr + (addr >> 1), 0x55);
    // Intel/AMD read id command
    FLASH_WRITE_HALFWORD (base_addr + addr,        0x90);

    *manufact = FLASH_READ_HALFWORD (base_addr);     // flash a0 = 0
    device[0] = FLASH_READ_HALFWORD (base_addr + 2); // flash a0 = 1

    // Read extended id
    device[1] = FLASH_READ_HALFWORD (base_addr + (0xE << 1));
    device[2] = FLASH_READ_HALFWORD (base_addr + (0xF << 1));

    FLASH_WRITE_HALFWORD (base_addr, 0xFF); // Intel read-array command

    // AMD devices do not need the two unlock cycles but SST devices do,
    // even though the SST datasheets states otherwise ;-)
    FLASH_WRITE_HALFWORD (base_addr + addr,        0xAA);
    FLASH_WRITE_HALFWORD (base_addr + (addr >> 1), 0x55);
    // AMD read-array/reset command
    FLASH_WRITE_HALFWORD (base_addr + addr,        0xF0);
}
#else

/* for CHIPSET == 15 */
// Convert a offset_t value to a block index

void ffsdrv_device_id_read(uint32 base_addr, uint16 *manufact, uint16 *device)
{
#ifdef INTEL_FLASH
   /* unlock cycle */
    FLASH_WRITE_HALFWORD (base_addr, 0x60);
    FLASH_WRITE_HALFWORD (base_addr, 0xD0);

    //Enter into auto select command
    FLASH_WRITE_HALFWORD (base_addr, 0x90);

    *manufact = FLASH_READ_HALFWORD (base_addr);
    device[0]=FLASH_READ_HALFWORD ((base_addr+0x02));

    // Read extended id
    device[1]=FLASH_READ_HALFWORD ((base_addr+0x0A));
    device[2]=0; //FLASH_READ_HALFWORD ((base_addr+0xF));

   /* Exit from auto select --- reset */
    FLASH_WRITE_HALFWORD (base_addr, 0xFF);
#else
    int addr, i;

    // This silly looking code has one purpose; to set addr = 0x555. It is
    // necessary in order to force the compiler NOT to produce code that
    // uses LDR opcode(s) with PC-relative addressing. The assember code
    // produced from this C code is completely relocatable!
    for (i = 0, addr = 0; i < 2; i++)
        addr |= addr << 4 | 0xAA;

   /* unlock cycle */
    FLASH_WRITE_HALFWORD ((base_addr+addr), 0xAA);

    FLASH_WRITE_HALFWORD ((base_addr+(addr>>1)), 0x55);

    //Enter into auto select command
    FLASH_WRITE_HALFWORD ((base_addr+addr),        0x90);

    *manufact = FLASH_READ_HALFWORD (base_addr);
    device[0]=FLASH_READ_HALFWORD ((base_addr+0x02));

    // Read extended id
    device[1]=FLASH_READ_HALFWORD ((base_addr+(0x0E<<1)));
    device[2]=FLASH_READ_HALFWORD ((base_addr+(0xF<<1)));

   /* Exit from auto select --- reset */
    FLASH_WRITE_HALFWORD (base_addr, 0xF0);
#endif
}
#endif

#define offset2block(offset) (((uint32) offset) >> dev.binfo[0].size_ld)

#ifdef AMD_FLASH
void ffsdrv_amd_fg_write_halfword(volatile uint16 *addr, uint16 value)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint32 cpsr;
    uint8 * offset;
    uint32 unlockOffset;
    static int badFlashCount=0;

   offset = (uint8*)addr - (uint32)(dev.base);
   unlockOffset = (dev.binfo[offset2block(offset)].offset+ 0x80)>>1;

   /* device state is write state */
   OS_LOCK_MUTEX(&ffs_write_mutex);
   dev.state=DEV_WRITE;
    /* Dissable the interrupts */
   cpsr=int_disable();

   /*LOCOSTO-Live Unlock Fix */
   flash[0]=0x0f0;
   flash[0]= 0x0060; // sector unlock sequence
   flash[0]= 0x0060; // sector unlock sequence
   flash[unlockOffset]= 0x0060; // sector unlock sequence (address 6 = VIH)

redowrite:
   flash[0]=0x0f0;

    /* two unlock cycles */
   flash[0x555]=0xAA;
   flash[0x2AA]=0x55;

   /* issue the program command now */
   flash[0x555]=0xA0;

   dev.addr=addr;    /* record the last write */
   dev.data=value;

   *addr = value;   /* this will be base+offset */

   /* Enable the interrupts */

   int_enable(cpsr);

   /* Wait for the write to complete */
   while (1)
   {
        unsigned short temp= (*addr);
        badFlashCount++;
        if(!((temp ^ dev.data) & 0x80))
            break;
        else if ((temp & 0x20))
        {
            if((((*addr) ^ dev.data) & 0x80))
                goto redowrite;
            break;
        }
        else
            continue;
   }/* Data polling */

   /* change the state to default read mode */
   dev.state=DEV_READ;

   OS_UNLOCK_MUTEX(&ffs_write_mutex);

}

void ffsdrv_amd_fg_write_halfword_local(volatile uint16 *addr, uint16 value)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint32 cpsr;
    uint8 * offset;
    uint32 unlockOffset;
    static int badFlashCount=0;

//   offset = (uint8*)addr - (uint32)(dev.base);
//   unlockOffset = (dev.binfo[offset2block(offset)].offset+ 0x80)>>1;

   /* device state is write state */
   OS_LOCK_MUTEX(&ffs_write_mutex);
   dev.state=DEV_WRITE;
    /* Dissable the interrupts */
   cpsr=int_disable();

   /*LOCOSTO-Live Unlock Fix */
//   flash[0]=0x0f0;
//   flash[0]= 0x0060; // sector unlock sequence
//   flash[0]= 0x0060; // sector unlock sequence
//   flash[unlockOffset]= 0x0060; // sector unlock sequence (address 6 = VIH)

redowrite:
   flash[0]=0x0f0;

    /* two unlock cycles */
   flash[0x555]=0xAA;
   flash[0x2AA]=0x55;

   /* issue the program command now */
   flash[0x555]=0xA0;

   dev.addr=addr;    /* record the last write */
   dev.data=value;

   *addr = value;   /* this will be base+offset */

   /* Enable the interrupts */

   int_enable(cpsr);

   /* Wait for the write to complete */
   while (1)
   {
        unsigned short temp= (*addr);
        badFlashCount++;
        if(!((temp ^ dev.data) & 0x80))
            break;
        else if ((temp & 0x20))
        {
            if((((*addr) ^ dev.data) & 0x80))
                goto redowrite;
            break;
        }
        else
            continue;
   }/* Data polling */

   /* change the state to default read mode */
   dev.state=DEV_READ;

   OS_UNLOCK_MUTEX(&ffs_write_mutex);

}

void ffsdrv_amd_fg_write_halfword_unlock_bypass(volatile uint16 *addr, uint16 value)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint32 cpsr;
    uint8 * offset;
    uint32 unlockOffset;
    static int badFlashCount=0;

//   offset = (uint8*)addr - (uint32)(dev.base);
//   unlockOffset = (dev.binfo[offset2block(offset)].offset+ 0x80)>>1;

   /* device state is write state */
   OS_LOCK_MUTEX(&ffs_write_mutex);
   dev.state=DEV_WRITE;
    /* Dissable the interrupts */
   cpsr=int_disable();

   /*LOCOSTO-Live Unlock Fix */
//   flash[0]=0x0f0;
//   flash[0]= 0x0060; // sector unlock sequence
//   flash[0]= 0x0060; // sector unlock sequence
//   flash[unlockOffset]= 0x0060; // sector unlock sequence (address 6 = VIH)

redowrite:
   flash[0]=0x0f0;

    /* two unlock cycles */
//   flash[0x555]=0xAA;
//   flash[0x2AA]=0x55;

   /* issue the program command now */
   flash[0x555]=0xA0;

   dev.addr=addr;    /* record the last write */
   dev.data=value;

   *addr = value;   /* this will be base+offset */

   /* Enable the interrupts */

   int_enable(cpsr);

   /* Wait for the write to complete */
   while (1)
   {
        unsigned short temp= (*addr);
        badFlashCount++;
        if(!((temp ^ dev.data) & 0x80))
            break;
        else if ((temp & 0x20))
        {
            if((((*addr) ^ dev.data) & 0x80))
                goto redowrite;
            break;
        }
        else
            continue;
   }/* Data polling */

   /* change the state to default read mode */
   dev.state=DEV_READ;

   OS_UNLOCK_MUTEX(&ffs_write_mutex);

}

void ffsdrv_amd_fg_write(void *dst, const void *src, uint16 size)
{
    uint8 *mydst = dst;
    const uint8 *mysrc = src;
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint8 * offset;
    uint32 unlockOffset;	
    uint32 unlock_bypass=0x0;
    uint32 cpsr;

/*#ifdef WCP_PROF
	prf_LogFunctionEntry((unsigned long) ffsdrv_amd_fg_write);
#endif */

    if (size > 0)
    {
        if ((unsigned int) mydst & 1) {
            ffsdrv_write_byte(mydst++, *mysrc++);
            size--;
        }
    if (size >=2)
    	{
	   offset = (uint8 *)dst - (uint32)(dev.base);
	   unlockOffset = (dev.binfo[offset2block(offset)].offset+ 0x80)>>1;
	   cpsr=int_disable();
	   	flash[0]=0x0f0;
	   	flash[0]= 0x0060; // sector unlock sequence
	   	flash[0]= 0x0060; // sector unlock sequence
	   	flash[unlockOffset]= 0x0060; // sector unlock sequence (address 6 = VIH)
	   int_enable(cpsr);

	   cpsr=int_disable();
	   // two unlock cycles
	   flash[0x555]=0xAA;
	   flash[0x2AA]=0x55;
	   // issue the program command now
	   flash[0x555]=0x20;
	   int_enable(cpsr);
	   unlock_bypass=1;	   
 
    	}
//	   cpsr=int_disable();	
        while (size >= 2) {
//            ffsdrv_amd_fg_write_halfword_local((uint16 *) mydst,  mysrc[0] | (mysrc[1] << 8));
            ffsdrv_amd_fg_write_halfword_unlock_bypass((uint16 *) mydst, mysrc[0] | (mysrc[1] << 8));

            size -= 2;
            mysrc += 2;
            mydst += 2;
        }
//	   int_enable(cpsr);
//#if 0
	if(unlock_bypass==1)
	{
		offset = (uint8*)dev.addr - (uint32)(dev.base);
		cpsr=int_disable();
		flash[dev.binfo[offset2block(offset)].offset] = 0x90;
		*(dev.addr) = 0x00;
//		flash[0]=0x0f0;		
	   	int_enable(cpsr);
	}
//#endif
		
        if (size == 1)
            ffsdrv_write_byte(mydst++, *mysrc++);
    }
/*#ifdef WCP_PROF
	prf_LogFunctionExit((unsigned long) ffsdrv_amd_fg_write);
#endif */

}




void ffsdrv_amd_fg_erase(uint8 block)
{
    uint16 *addr = (uint16 *) block2addr(block);
    ffsdrv.erase_sector(addr);
}

void ffsdrv_amd_fg_erase_sector(void *dst)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint32 cpsr;
    uint32 unlockOffset;

    dev.addr = (uint16 *) dst;
    unlockOffset = ((uint32)(dev.addr)-(uint32)(dev.base) + 0x80) >> 1;

    /* change the device status */
    dev.state=DEV_ERASE;

   /* disable the interrupts */
   cpsr=int_disable();
   /*LOCOSTO-Live Unlock Fix */
   flash[0]=0x0f0;
   flash[0]= 0x0060; // sector unlock sequence
   flash[0]= 0x0060; // sector unlock sequence
   flash[unlockOffset]= 0x0060; // sector unlock sequence (address 6 = VIH)
   flash[0]=0x0f0;

   /* sector erase command -- 6 cycles */
   flash[0x555] =0xAA;
   flash[0x2AA]=0x55;
   flash[0x555]=0x80;
   flash[0x555]= 0xAA;
   flash[0x2AA]=0x55;
   *((volatile uint16*)(dev.addr))=0x30;   /* write the command to sector address */

   /* Enable the interrupts */
   int_enable(cpsr);

 /* Wait for the erase to complete  */
    while ((*dev.addr & 0x80) == 0);   /* DQ7 will have 1 on completion of erase */  /* Data polling */

 /* change the device state  to default READ mode */
    dev.state=DEV_READ;

}



//OMAPS62129 Create NEW pseudo SB erase function for AMD_NOR (Isample v1.x)
//This version allows the 3Mb of Flash not used by 1Mb FFS in Block C to
//be reused for other code/data.
void ffsdrv_amd_fg_erase_sector_pseudo_sb(void *dst)
{
    volatile uint16 *flash = (volatile uint16*)dev.base;
    uint32 cpsr;
    uint32 unlockOffset;


    dev.addr = (uint16 *) dst;
    unlockOffset = ((uint32)(dev.addr)-(uint32)(dev.base) + 0x80) >> 1;

    /* change the device status */
    dev.state=DEV_ERASE;

   ttw(ttr(TTrDrvErase, "e(%d){" NL, dst));
   /* disable the interrupts */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -