📄 dram.c
字号:
DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L)); DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL)); DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL)); i = 0; for (j = 0; j < size; j++) { n = EMERGENCYCOUNTER; do { // wait if FIFO empty flag = DecoderReadByte(card, 0x0C0); } while ((flag & 0x01) && n--); if (n<0) return -1; b = DecoderReadByte(card, 0x0C2); data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); b = DecoderReadByte(card, 0x0C2); data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); b = DecoderReadByte(card, 0x0C2); data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); b = DecoderReadByte(card, 0x0C2); data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); } n = EMERGENCYCOUNTER; do { // wait if FIFO empty flag = DecoderReadByte(card, 0x0C0); } while ((flag & 0x01) && n--); if (n<0) return -1; for (j = 0; j < rsize; j++) { b = DecoderReadByte(card, 0x0C2); data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2)); } flag = DecoderReadByte(card, 0x0C0); n = EMERGENCYCOUNTER; do { // wait for FIFO full flag = DecoderReadByte(card, 0x0C0); } while (!(flag & 0x02) && n--); return ((n>=0) ? 0 : -1);} // where: 21 bit DRAM Word-Address, 4 word aligned // size: words // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.) // returns -1 on success (equal content), // word position on error (compare failure), // -2 on collision with DMA transferint DRAMVerifyWord(struct cvdv_cards *card, u32 where, int size, u16 * data, int swap){ int i, j, rsize, n; u8 volatile flag, b; rsize = size & 3; // padding words size >>= 2; // 4 words at a time where >>= 2; // 8 byte aligned data, now 19 bit 64-bit-word-address//TODO: swap manually if (swap) DecoderDelByte(card, 0x0C1, 0x08); // byte swapping of 8 byte bursts else DecoderSetByte(card, 0x0C1, 0x08); // no byte swapping DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L)); DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL)); DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL)); i = 0; for (j = 0; j < size; j++) { n = EMERGENCYCOUNTER; do { // wait if FIFO empty flag = DecoderReadByte(card, 0x0C0); } while ((flag & 0x01) && n--); b = DecoderReadByte(card, 0x0C2); if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) return i; b = DecoderReadByte(card, 0x0C2); if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) return i; b = DecoderReadByte(card, 0x0C2); if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) return i; b = DecoderReadByte(card, 0x0C2); if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) return i; } n = EMERGENCYCOUNTER; do { // wait if FIFO empty flag = DecoderReadByte(card, 0x0C0); } while ((flag & 0x01) && n--); for (j = 0; j < rsize; j++) { b = DecoderReadByte(card, 0x0C2); if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2))) return i; } flag = DecoderReadByte(card, 0x0C0); n = EMERGENCYCOUNTER; do { // wait for FIFO full flag = DecoderReadByte(card, 0x0C0); } while (!(flag & 0x02) && n--); return -1;} // WARNING: better not use this one. It can collide with normal DRAM access and other DMA transfers // If you want to use it, implement card->DMAMoveBusy in all other DMA functions, initialisation, and header file // source, destination: 21 bit DRAM Word-Address, 4 word aligned // size: byte (8 byte aligned, hang over bytes will NOT be moved) // returns 0 on success on success, // -1 on collision with DMA transfer,// -2 on interrupt handler not installedint DRAMMove(struct cvdv_cards *card, u32 source, u32 destination, int size){ if (!card->IntInstalled) return -2; if (card->DMAABusy || card->DMABBusy) return -1; size >>= 3; // 64-bit-words source >>= 2; // 8 byte aligned data, destination >>= 2; // now 19 bit 64-bit-word-address DecoderDelByte(card, 0x0C1, 0x06); // DMA idle DecoderWriteByte(card, 0x0DA, (u8) ((source >> 16) & 0x00000007L)); DecoderWriteByte(card, 0x0D9, (u8) ((source >> 8) & 0x000000FFL)); DecoderWriteByte(card, 0x0D8, (u8) (source & 0x000000FFL)); DecoderWriteByte(card, 0x0D7, (u8) ((destination >> 16) & 0x00000007L)); DecoderWriteByte(card, 0x0D6, (u8) ((destination >> 8) & 0x000000FFL)); DecoderWriteByte(card, 0x0D5, (u8) (destination & 0x000000FFL)); //card->DMAMoveBusy=1; // would have to catch that in all the other DMA routines DecoderSetByte(card, 0x0C1, 0x06); // DMA block move return 0;} // size in words // align: number of words on wich start of block will be aligned// return value is 21 bit word address, or 0xFFFFFFFF on erroru32 DRAMAlloc(struct cvdv_cards * card, u32 size, int align){ struct DRAMBlock *ptr, *ptr2; u32 addr = 0; u32 alignmask = align - 1; int valid = 0; if (!card || size == 0) return BLANK; if (size & 3) size = (size & ~3) + 4; // increase size if not 64 bit aligned if (card->DRAMFirstBlock == NULL) { // virgin territory? valid = ((addr + size) <= card->DRAMSize); // does it fit at all? } else { addr = 0; valid = ((addr + size) <= card->DRAMSize); // does it fit at all? for (ptr2 = card->DRAMFirstBlock; (ptr2 != NULL) && (valid); ptr2 = ptr2->next) { // check against all existing blocks if ((ptr2->start >= addr) && (ptr2->start < (addr + size))) valid = 0; // existing block start inside new block? else if (((ptr2->start + ptr2->length) > addr) && ((ptr2->start + ptr2->length) <= (addr + size))) valid = 0; // existing block end inside new block? else if ((ptr2->start < addr) && ((ptr2->start + ptr2->length) > (addr + size))) valid = 0; // new block inside existing block? } for (ptr = card->DRAMFirstBlock; (ptr != NULL) && (!valid); ptr = ptr->next) { // check all existing blocks addr = ptr->start + ptr->length; // assume, after this block is free space if (addr & alignmask) addr = (addr & ~alignmask) + align; // round up to alignation border valid = ((addr + size) <= card->DRAMSize); // does it fit at all? for (ptr2 = card->DRAMFirstBlock; (ptr2 != NULL) && (valid); ptr2 = ptr2->next) { // check against all existing blocks if ((ptr2->start >= addr) && (ptr2->start < (addr + size))) valid = 0; // existing block start inside new block? else if ( ((ptr2->start + ptr2->length) > addr) && ((ptr2->start + ptr2->length) <= (addr + size))) valid = 0; // existing block end inside new block? else if ((ptr2->start < addr) && ((ptr2->start + ptr2->length) > (addr + size))) valid = 0; // new block inside existing block? } } } if (valid) { // The new block fits ptr = (struct DRAMBlock *) kmalloc(sizeof(struct DRAMBlock), GFP_KERNEL); if (ptr == NULL) { printk(KERN_INFO LOGNAME ": ERROR: out of kernel memory. Please reboot if possible.\n"); return BLANK; // out of kernel mem } if (card->DRAMFirstBlock == NULL) { card->DRAMFirstBlock = ptr; } else { ptr2 = card->DRAMFirstBlock; while (ptr2->next != NULL) ptr2 = ptr2->next; ptr2->next = ptr; } ptr->next = NULL; ptr->start = addr; ptr->length = size; MDEBUG(1,": DRAM Allocate 0x%08X-0x%08X\n", addr, addr + size - 1); return addr; } return BLANK;} // addr is the return value of that resp. DRAMAlloc call// returns 0 on success (always)int DRAMFree(struct cvdv_cards *card, u32 addr){ struct DRAMBlock *ptr, *ptr2; ptr2 = NULL; for (ptr = card->DRAMFirstBlock; ptr != NULL; ptr = ptr->next) { // check all existent blocks if (addr == ptr->start) { // this is our block to be removed if (ptr2 == NULL) card->DRAMFirstBlock = ptr->next; else ptr2->next = ptr->next; if (ptr) kfree(ptr); MDEBUG(1, ": DRAM Free 0x%08X\n", addr); } else ptr2 = ptr; } return 0;} // free all blocks// returns 0 on success (always)int DRAMRelease(struct cvdv_cards *card){ struct DRAMBlock *ptr, *ptr2; MDEBUG(1, ": -- DRAMRelease\n"); for (ptr = card->DRAMFirstBlock; ptr != NULL; ptr = ptr2) { // check all existent blocks ptr2 = ptr->next; MDEBUG(4, ": kfree(0x%08X)\n",(int)ptr); kfree(ptr); } card->DRAMFirstBlock = NULL; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -