/** Write an unknown control code into the BNEP not understood control response @internalComponent */ void RBnepNotUnderstoodResponseControl::SetUnknownControlType (TUint8 aUnknownControlType) { LOG_FUNC TPckgBuf<TUint8> controlType(static_cast<TUint8>(EBnepControlCommandNotUnderstood)); TPckgBuf<TUint8> unknownControlType(aUnknownControlType); CopyIn(controlType, KControlTypeOffset); CopyIn(unknownControlType, KUnknownControlTypeResponseFieldOffset); DUMPFRAME(_L8("RBnepNotUnderstoodResponseControl")); }
SYSCALL vm_addr GetCachedSegment (uint64 *in_segment_id) { struct Process *current; struct Segment *seg; uint64 segment_id; uint64 key; current = GetCurrentProcess(); CopyIn (&segment_id, in_segment_id, sizeof (segment_id)); key = segment_id % CACHE_HASH_SZ; seg = LIST_HEAD (&cache_hash[key]); DisablePreemption(); while (seg != NULL) { if (seg->segment_id == segment_id && seg->owner == current) { LIST_REM_ENTRY (&cache_lru_list, seg, lru_link); LIST_REM_ENTRY (&cache_hash[key], seg, hash_link); if (seg == last_aged_seg) last_aged_seg = NULL; return seg->base; } seg = LIST_NEXT (seg, hash_link); } return (vm_addr)NULL; }
/** Initialise the role UUIDs. @internalComponent */ void RBnepSetupConnectionRequestControl::SetRolesL (TUUID& aLocalRole, TUUID& aRemoteRole) { LOG_FUNC TInt uuidSize = Max(aLocalRole.MinimumSize(), aRemoteRole.MinimumSize()); TBuf8<2*sizeof(TUint8)> header; header.SetMax(); header[KControlTypeOffset] = EBnepSetupConnectionRequestMessage; header[KUUIDSizeOffset] = static_cast<TUint8>(uuidSize); CopyIn(header); TPtrC8 uuid; uuid.Set(aRemoteRole.SpecifiedLengthL(uuidSize)); CopyIn(uuid, KUUIDOffset); uuid.Set(aLocalRole.SpecifiedLengthL(uuidSize)); CopyIn(uuid, KUUIDOffset + uuidSize); TrimEnd(KUUIDOffset + (2 * uuidSize)); DUMPFRAME(_L8("RBnepSetupConnectionRequestControl")); }
SYSCALL int ExpungeCachedSegment (uint64 *in_segment_id) { struct Process *current; struct Segment *seg; uint64 segment_id; uint64 key; current = GetCurrentProcess(); CopyIn (&segment_id, in_segment_id, sizeof (segment_id)); key = segment_id % CACHE_HASH_SZ; seg = LIST_HEAD (&cache_hash[key]); DisablePreemption(); while (seg != NULL) { if (seg->segment_id == segment_id && seg->owner == current) { LIST_REM_ENTRY (&cache_lru_list, seg, lru_link); LIST_REM_ENTRY (&cache_hash[key], seg, hash_link); if (seg == last_aged_seg) last_aged_seg = NULL; HEAP_ADD_HEAD (&free_segment_list[seg->bucket_q], seg, link); seg->size = 0; seg->physical_addr = (vm_addr)NULL; seg->flags = MEM_FREE; seg->owner = NULL; PmapRemoveRegion (seg); return 0; } else if (seg->segment_id == segment_id && seg->owner != current) { return memoryErr; } seg = LIST_NEXT (seg, hash_link); } return memoryErr; }
int DuplicateAddressSpace (struct AddressSpace *src_as, struct AddressSpace *dst_as) { struct MemRegion *mr; struct Pageframe *pf; int error = 0; uint32 prot; struct AddressSpace *old_as; if (AllocDupAddressSpace (src_as, dst_as) == 0) { mr = LIST_HEAD (&dst_as->sorted_memregion_list); while (mr != NULL && error == 0) { if (mr->type == MR_TYPE_ANON) { prot = mr->prot; old_as = SwitchAddressSpace (dst_as); UProtect (mr->base_addr, VM_PROT_READWRITE); SwitchAddressSpace (old_as); /* IMPROVEMENT: * * Try to copy upto 64k (VM_TEMP_BUF_SZ) worth of linear * pages at a time, reduces number of task switches * and concentrates on inner loops */ pf = LIST_HEAD (&mr->pageframe_list); while (pf != NULL && error == 0) { error = CopyIn (src_as, (void *)vm_temp_buf, (void *)pf->virtual_addr, PAGE_SIZE); if (error == 0) error = CopyOut (dst_as, (void *)pf->virtual_addr, (void *)vm_temp_buf, PAGE_SIZE); pf = LIST_NEXT (pf, memregion_entry); } old_as = SwitchAddressSpace (dst_as); UProtect (mr->base_addr, prot); SwitchAddressSpace (old_as); } mr = LIST_NEXT (mr, sorted_entry); } if (error != 0) FreeAddressSpace (dst_as); } else error = -1; KASSERT (error != -1); return error; }
SYSCALL int Spawn (struct SpawnArgs *user_sa, void **user_segments, int segment_cnt) { struct Process *proc, *current; void *segments[NSPAWNSEGMENTS]; struct Segment *vs_ptrs[NSPAWNSEGMENTS]; int h; int t; struct SpawnArgs sa; current = GetCurrentProcess(); if (!(current->flags & PROCF_FILESYS)) return privilegeErr; if (segment_cnt < 1 || segment_cnt > NSPAWNSEGMENTS) return paramErr; CopyIn (&sa, user_sa, sizeof sa); CopyIn (segments, user_segments, sizeof (void *) * segment_cnt); if (free_handle_cnt < (1 + 3 + 1) || free_process_cnt < 1) return resourceErr; if (sa.namespace_handle == -1) return paramErr; if (FindHandle (current, sa.namespace_handle) == NULL) return paramErr; if (SegmentFindMultiple (vs_ptrs, segments, segment_cnt) < 0) return paramErr; DisablePreemption(); h = AllocHandle(); proc = AllocProcess(); proc->handle = h; proc->flags = sa.flags & ~PROCF_SYSTEMMASK; proc->namespace_handle = sa.namespace_handle; handle_table[sa.namespace_handle].owner = proc; handle_table[sa.namespace_handle].flags |= HANDLEF_GRANTED_ONCE; proc->sighangup_handle = AllocHandle(); SetObject (proc, proc->sighangup_handle, HANDLE_TYPE_SYSTEMEVENT, NULL); handle_table[proc->sighangup_handle].flags |= HANDLEF_GRANTED_ONCE; proc->sigterm_handle = AllocHandle(); SetObject (proc, proc->sigterm_handle, HANDLE_TYPE_PROCESS, NULL); handle_table[proc->sigterm_handle].flags |= HANDLEF_GRANTED_ONCE; current->argv = sa.argv; current->argc = sa.argc; current->envv = sa.envv; current->envc = sa.envc; ArchAllocProcess(proc, sa.entry, sa.stack_top); SetObject (current, h, HANDLE_TYPE_PROCESS, proc); for (t=0; t < segment_cnt; t++) { PmapRemoveRegion (vs_ptrs[t]); vs_ptrs[t]->owner = proc; } proc->state = PROC_STATE_READY; SchedReady(proc); return h; }