ot_u16 vworm_read(vaddr addr) { #if (VWORM_SIZE > 0) ot_u16* a_ptr; ot_u16* p_ptr; ot_int offset; ot_int index; SEGFAULT_CHECK(addr, in_vworm, 7, "VLC_415"); //__LINE__ /// 1. Resolve the vaddr directly offset = addr & (VWORM_PAGESIZE-1); index = (addr-VWORM_BASE_VADDR) >> VWORM_PAGESHIFT; p_ptr = PTR_OFFSET(X2table.block[index].primary, offset); /// 2. return either the primary pointer in full or the XNOR if (X2table.block[index].ancillary == NULL) { return *p_ptr; } a_ptr = PTR_OFFSET(X2table.block[index].ancillary, offset); return ~(*p_ptr ^ *a_ptr); #else return 0; #endif }
ot_u16 vsram_read(vaddr addr) { #if (VSRAM_SIZE <= 0) return 0; #else SEGFAULT_CHECK(addr, in_vsram, 7, "VLC_" __LINE__); //__LINE__ addr -= VSRAM_BASE_VADDR; return vsram[addr>>1]; #endif }
ot_u8 vworm_write(vaddr addr, ot_u16 data) { #if ((VWORM_SIZE > 0) && (OT_FEATURE_VLNVWRITE == ENABLED)) SEGFAULT_CHECK(addr, in_vworm, 7, "VLC_" __LINE__); //__LINE__ return vworm_mark_physical( (ot_u16*)(((ot_u32)addr)+VWORM_BASE_PHYSICAL), data ); #else return 0; #endif }
ot_u8 vsram_mark(vaddr addr, ot_u16 value) { #if (VSRAM_SIZE <= 0) return ~0; #else SEGFAULT_CHECK(addr, in_vsram, 7, "VLC_" __LINE__); //__LINE__ addr -= VSRAM_BASE_VADDR; vsram[addr>>1] = value; return 0; #endif }
ot_u8* vsram_get(vaddr addr) { #if (VSRAM_SIZE <= 0) return NULL; #else ot_u8* output; SEGFAULT_CHECK(addr, in_vsram, 7, "VLC_" __LINE__); addr -= VSRAM_BASE_VADDR; output = (ot_u8*)vsram + addr; return output; #endif }
ot_u16 vworm_read(vaddr addr) { #if ((VWORM_SIZE > 0) && (OT_FEATURE(VLNVWRITE) == ENABLED)) ot_u32 paddr; SEGFAULT_CHECK(addr, in_vworm, 7, "VLC_" __LINE__); //__LINE__ paddr = (addr+VWORM_BASE_PHYSICAL); return *((ot_u16*)paddr); #else return 0; #endif }
ot_u8 vworm_write(vaddr addr, ot_u16 data) { #if ((VWORM_SIZE > 0) && (OT_FEATURE_VLNVWRITE == ENABLED)) ot_int index; ot_int offset; ot_u16 wrtest; ot_u16* p_ptr; ot_u16* a_ptr; SEGFAULT_CHECK(addr, in_vworm, 7, "VLC_445"); //__LINE__ /// 1. Resolve the vaddr directly offset = addr & (VWORM_PAGESIZE-1); index = (addr-VWORM_BASE_VADDR) >> VWORM_PAGESHIFT; p_ptr = PTR_OFFSET(X2table.block[index].primary, offset); /// 2. No ancillary block, but try a write anyway if (X2table.block[index].ancillary == NULL) { /// 2a. If no 0->1 write requirement, then we're good to go if ((data & ~(*p_ptr)) == 0) { return vworm_mark_physical(p_ptr, data); } /// 2b. Attach a fallow to this bitch (it becomes ancillary) sub_attach_fallow(&X2table.block[index]); } /// 3. There is ancillary block, so go through the logical write process, /// which is designed to shake out a write out of whatever it can get. /// The only bit combination that cannot be managed is [1->0 via 0,0] a_ptr = PTR_OFFSET(X2table.block[index].ancillary, offset); wrtest = ~data & ~(*p_ptr) & ~(*a_ptr); if (wrtest == 0) { ot_u8 test = 0; /// 3a. Adjust cases where [1->0 via 1,1] or [0->1 via 1,0] wrtest = ~data & *p_ptr & *a_ptr; wrtest |= data & *p_ptr & ~(*a_ptr); if (wrtest != 0) { test |= vworm_mark_physical(p_ptr, *p_ptr ^ wrtest); } /// 3b. Adjust cases where [0->1 via 0,1] wrtest = data & ~(*p_ptr) & *a_ptr; if (wrtest != 0) { test |= vworm_mark_physical(a_ptr, *a_ptr ^ wrtest); } return test; } /// 4. Recombine this block, with the exception of the given addr offset, /// which we will then write-to else { p_ptr = sub_recombine_block(&X2table.block[index], offset, 2); return vworm_mark_physical(p_ptr, data); } #else return 0; #endif }
ot_u8 vfram_wipeblock(vaddr addr, ot_uint wipe_span) { SEGFAULT_CHECK(addr, in_vworm, 15, "vfram_wipeblock"); ot_memset((ot_u16*)addr, 0, wipe_span); return 0; }
ot_u8* vfram_get(vaddr addr) { SEGFAULT_CHECK(addr, in_vworm, 9, "vfram_get"); return (ot_u8*)addr; }
ot_u8 vfram_mark(vaddr addr, ot_u16 value) { SEGFAULT_CHECK(addr, in_vworm, 10, "vfram_mark"); return vfram_mark_physical((ot_u16*)addr, value); }
/** VSRAM Functions <BR> * ========================================================================<BR> */ ot_u16 vfram_read(vaddr addr) { SEGFAULT_CHECK(addr, in_vworm, 10, "vfram_read"); return *addr; }