static struct rktag_header * kld_get_current( void ) { struct rktag_header *h = rkh_begin; while( h->tag != RKTAG_NONE ) { if( NEXT_TAG( h ) > rkh_end ) break; h = NEXT_TAG( h ); } return h; }
static void handle_ani_list(riff_tag_t *lst, enum res_e type, int isswapped) { riff_tag_t *rtp = lst+1; /* Skip the "LIST" tag */ while((char *)rtp < (char *)lst + lst->size + sizeof(*lst)) { if(!memcmp(rtp->tag, info, sizeof(info))) { rtp = SKIP_TAG(rtp,4); } else if(!memcmp(rtp->tag, inam, sizeof(inam))) { /* Ignore the icon/cursor name; its a string */ rtp = NEXT_TAG(rtp); } else if(!memcmp(rtp->tag, iart, sizeof(iart))) { /* Ignore the author's name; its a string */ rtp = NEXT_TAG(rtp); } else if(!memcmp(rtp->tag, fram, sizeof(fram))) { /* This should be followed by "icon"s, but we * simply ignore this because it is pure * non-information. */ rtp = SKIP_TAG(rtp,4); } else if(!memcmp(rtp->tag, icon, sizeof(icon))) { handle_ani_icon(rtp, type, isswapped); rtp = NEXT_TAG(rtp); } else internal_error(__FILE__, __LINE__, "Unknown tag \"%c%c%c%c\" in RIFF file", isprint(rtp->tag[0]) ? rtp->tag[0] : '.', isprint(rtp->tag[1]) ? rtp->tag[1] : '.', isprint(rtp->tag[2]) ? rtp->tag[2] : '.', isprint(rtp->tag[3]) ? rtp->tag[3] : '.'); if((UINT_PTR)rtp & 1) rtp = SKIP_TAG(rtp,1); } }
/* * for kernel set tag to loader or loader set tag to kernel. * FIXME:need to disable irq ?? */ int kld_set_tag( struct rktag_header * h ) { struct rktag_header *h0 = kld_find_tag( h->tag ); if( h0 ) { memcpy( h0 , h , h->size ); return 0; } if( (char*)rkh_current+h->size > (char*)rkh_end ) return -ENOMEM; memcpy( rkh_current , h , h->size ); rkh_current = NEXT_TAG(rkh_current); return 0; }
static struct rktag_header * kld_find_tag( __u32 tag ) { struct rktag_header *h = rkh_begin; /* find loader to kernel */ while( h < rkh_current ) { if( h->tag == tag ) return h; if( h->tag == RKTAG_NONE ) break; h = NEXT_TAG( h ); } return NULL; }
ani_curico_t *new_ani_curico(enum res_e type, raw_data_t *rd, int *memopt) { ani_curico_t *ani = (ani_curico_t *)xmalloc(sizeof(ani_curico_t)); riff_tag_t *rtp; int isswapped = 0; int doswap; const char *anistr = type == res_aniico ? "icon" : "cursor"; assert(!memcmp(rd->data, riff, sizeof(riff))); assert(type == res_anicur || type == res_aniico); rtp = (riff_tag_t *)rd->data; if(BYTESWAP_DWORD(rtp->size) + 2*sizeof(DWORD) == rd->size) isswapped = 1; else if(rtp->size + 2*sizeof(DWORD) == rd->size) isswapped = 0; else yyerror("Animated %s has an invalid RIFF length", anistr); switch(byteorder) { #ifdef WORDS_BIGENDIAN case WRC_BO_LITTLE: #else case WRC_BO_BIG: #endif doswap = !isswapped; break; default: doswap = isswapped; } /* * When to swap what: * isswapped | doswap | * ----------+--------+--------------------------------- * 0 | 0 | read native; don't convert * 1 | 0 | read swapped size; don't convert * 0 | 1 | read native; convert * 1 | 1 | read swapped size; convert * Reading swapped size if necessary to calculate in native * format. E.g. a little-endian source on a big-endian * processor. */ if(doswap) { /* We only go through the RIFF file if we need to swap * bytes in words/dwords. Else we couldn't care less * what the file contains. This is consistent with * MS' rc.exe, which doesn't complain at all, even though * the file format might not be entirely correct. */ rtp++; /* Skip the "RIFF" tag */ while((char *)rtp < (char *)rd->data + rd->size) { if(!memcmp(rtp->tag, acon, sizeof(acon))) { rtp = SKIP_TAG(rtp,4); } else if(!memcmp(rtp->tag, list, sizeof(list))) { handle_ani_list(rtp, type, isswapped); rtp = NEXT_TAG(rtp); } else if(!memcmp(rtp->tag, anih, sizeof(anih))) { aniheader_t *ahp = (aniheader_t *)((char *)(rtp+1)); ahp->structsize = BYTESWAP_DWORD(ahp->structsize); ahp->frames = BYTESWAP_DWORD(ahp->frames); ahp->steps = BYTESWAP_DWORD(ahp->steps); ahp->cx = BYTESWAP_DWORD(ahp->cx); ahp->cy = BYTESWAP_DWORD(ahp->cy); ahp->bitcount = BYTESWAP_DWORD(ahp->bitcount); ahp->planes = BYTESWAP_DWORD(ahp->planes); ahp->rate = BYTESWAP_DWORD(ahp->rate); ahp->flags = BYTESWAP_DWORD(ahp->flags); rtp = NEXT_TAG(rtp); } else if(!memcmp(rtp->tag, rate, sizeof(rate))) { int cnt = rtp->size / sizeof(DWORD); DWORD *dwp = (DWORD *)(rtp+1); int i; for(i = 0; i < cnt; i++) dwp[i] = BYTESWAP_DWORD(dwp[i]); rtp = NEXT_TAG(rtp); } else if(!memcmp(rtp->tag, seq, sizeof(seq))) { int cnt = rtp->size / sizeof(DWORD); DWORD *dwp = (DWORD *)(rtp+1); int i; for(i = 0; i < cnt; i++) dwp[i] = BYTESWAP_DWORD(dwp[i]); rtp = NEXT_TAG(rtp); } else internal_error(__FILE__, __LINE__, "Unknown tag \"%c%c%c%c\" in RIFF file", isprint(rtp->tag[0]) ? rtp->tag[0] : '.', isprint(rtp->tag[1]) ? rtp->tag[1] : '.', isprint(rtp->tag[2]) ? rtp->tag[2] : '.', isprint(rtp->tag[3]) ? rtp->tag[3] : '.'); if((UINT_PTR)rtp & 1) rtp = SKIP_TAG(rtp,1); } /* We must end correctly here */ if((char *)rtp != (char *)rd->data + rd->size) yyerror("Animated %s contains invalid field size(s)", anistr); } ani->data = rd; if(memopt) { ani->memopt = *memopt; free(memopt); } else ani->memopt = WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE; return ani; }
void __init rk28_kld_init( void ) { struct rktag_header * h; rk28_arch_reset = rk28_kld_reset ; //rk28_enable_wdt_to_restat; rkh_current = rkh_end; memset( rkh_begin , 0 , sizeof rkld_param ); h = (struct rktag_header *)0xc0002000; if( h->tag == RKTAG_IDTAG && h->size == RKTAG_IDSIZE ) { h->tag = KRTAG_IDTAG; } else if( h->tag != KRTAG_IDTAG || h->size != RKTAG_IDSIZE ) { //printk("%s:: found invalid tag=0x%x,size=0x%x\n" , __func__ , // h->tag , h->size); rkh_current = h; goto kld_set; //return; } memcpy( rkh_begin , h , sizeof rkld_param ); h = rkh_begin; if( h->tag == KRTAG_IDTAG && h->size == RKTAG_IDSIZE ) { h = NEXT_TAG( h ); while( h->tag != RKTAG_NONE && h < rkh_end ) { #if 0 struct kld_tag *tg = (struct kld_tag *)h; switch (h->tag) { case RKTAG_CHIP: { struct rktag_chip * p = (struct rktag_chip*)(h+1); printk("%s::get RKTAG_CHIP,size=0x%x,chipxxx=0x%x,reserved blk=%d,rkh_begin=0x%p\n" , __func__ , h->size-8 ,p->chip_xxx,p->total_reserved_blocks,rkh_begin); } break; case RKTAG_RUNTIME: printk("%s::load timer=%d ms\n" , __func__ , tg->u.rt.total_ms ); break; case RKTAG_VERSION: printk("%s::load date=%x , version=%x.%x\n" , __func__ , tg->u.lver.date , tg->u.lver.main_version , tg->u.lver.min_version ); break; case RKTAG_CHECKCODE: // printk("%s::code start=%x , size=%d\n" , __func__ , tg->u.ck.va_start , tg->u.ck.length ); break; case RKTAG_BOOTFLAG: // printk("%s::boot flag=%x\n" , __func__ , tg->u.bf.flag ); break; case RKTAG_IDBLK_CHIPINFO: break; case RKTAG_IDBLK_SERIAL: break; default: printk("%s::unknow tag=0x%x\n" , __func__ , h->tag ); break; } #else //printk("%s::get tag=0x%x,size=0x%x,rkh_begin=0x%p\n" , __func__ ,h->tag, // h->size-8 , rkh_begin); #endif h = NEXT_TAG( h ); } if( h >= rkh_end ) return ; rkh_current = h; } kld_set: rk28_set_check_data((__u32)rk28_panic_reset , 0 , 0 , 0); kld_set_reset_flag( 2 , 0 ); /* 0: normal , 1:loader usb */ }