APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, const char *filename, apr_pool_t *pool) { area_info ai; thread_info ti; apr_shm_t *new_m; area_id deleteme = find_area(filename); if (deleteme == B_NAME_NOT_FOUND) return APR_EINVAL; new_m = (apr_shm_t*)apr_palloc(pool, sizeof(apr_shm_t*)); if (new_m == NULL) return APR_ENOMEM; new_m->pool = pool; get_area_info(deleteme, &ai); get_thread_info(find_thread(NULL), &ti); if (ti.team != ai.team) { area_id narea; narea = clone_area(ai.name, &(ai.address), B_CLONE_ADDRESS, B_READ_AREA|B_WRITE_AREA, ai.area); if (narea < B_OK) return narea; get_area_info(narea, &ai); new_m->aid = narea; new_m->memblock = ai.address; new_m->ptr = (void*)ai.address; new_m->avail = ai.size; new_m->reqsize = ai.size; } (*m) = new_m; return APR_SUCCESS; }
status_t LinkReceiver::Read(void *data, ssize_t passedSize) { // STRACE(("info: LinkReceiver Read()ing %ld bytes...\n", size)); ssize_t size = passedSize; if (fReadError < B_OK) return fReadError; if (data == NULL || size < 1) { fReadError = B_BAD_VALUE; return B_BAD_VALUE; } if (fDataSize == 0 || fReplySize == 0) return B_NO_INIT; // need to call GetNextReply() first bool useArea = false; if ((size_t)size >= kMaxBufferSize) { useArea = true; size = sizeof(area_id); } if (fRecvPosition + size > fRecvStart + fReplySize) { // reading past the end of current message fReadError = B_BAD_VALUE; return B_BAD_VALUE; } if (useArea) { area_id sourceArea; memcpy((void*)&sourceArea, fRecvBuffer + fRecvPosition, size); area_info areaInfo; if (get_area_info(sourceArea, &areaInfo) < B_OK) fReadError = B_BAD_VALUE; if (fReadError >= B_OK) { void* areaAddress = areaInfo.address; if (areaAddress && sourceArea >= B_OK) { memcpy(data, areaAddress, passedSize); delete_area(sourceArea); } } } else { memcpy(data, fRecvBuffer + fRecvPosition, size); } fRecvPosition += size; return fReadError; }
BBufferGroup *VideoRecorderNode::GetBitmapBufferGroup(void) { BBufferGroup *my_group = new BBufferGroup; area_info bm_info; if (bitmap != NULL) { if (get_area_info(bitmap->Area(), &bm_info) != B_OK) return NULL; buffer_clone_info bc_info; bc_info.area = bm_info.area; bc_info.offset = ((char *) bitmap->Bits())-((char *) bm_info.address); bc_info.size = bitmap->BitsLength(); BBuffer *out_buffer = NULL; if(my_group->AddBuffer(bc_info, &out_buffer) != B_OK) return NULL; else { out_buffer->Recycle(); return my_group; } } else return NULL; }
static guarded_heap_page* guarded_heap_area_allocation_for(void* address, area_id& allocationArea) { allocationArea = area_for(address); if (allocationArea < 0) return NULL; area_info areaInfo; if (get_area_info(allocationArea, &areaInfo) != B_OK) return NULL; guarded_heap_page* page = (guarded_heap_page*)areaInfo.address; if (page->flags != (GUARDED_HEAP_PAGE_FLAG_USED | GUARDED_HEAP_PAGE_FLAG_FIRST | GUARDED_HEAP_PAGE_FLAG_AREA)) { return NULL; } if (page->allocation_base != address) return NULL; if (page->allocation_size >= areaInfo.size) return NULL; return page; }
void AreaLink::SetTarget(area_id area, bool isAreaLinkArea) { area_info targetInfo; if (get_area_info(area, &targetInfo) == B_OK) { fTarget = area; fAreaIsOk = true; fHeader = (AreaLinkHeader *)targetInfo.address; if (isAreaLinkArea) _ReadAttachments(); else { fHeader->MakeEmpty(); fHeader->SetInfo(targetInfo); } fBaseAddress = (int8*)targetInfo.address; fBaseAddress += sizeof(AreaLinkHeader); } else { fTarget = B_NAME_NOT_FOUND; fAreaIsOk = false; } }
template<typename R> status_t operator()(R* request) { // check the request buffer size if (fRequestBufferSize < (int32)sizeof(R)) RETURN_ERROR(B_BAD_DATA); // no need to relocate the addresses of a reply that indicates an error if (is_error_reply(request)) { fSuccess = true; return B_OK; } // get the address infos AddressInfo infos[MAX_REQUEST_ADDRESS_COUNT]; int32 count = 0; status_t error = request->GetAddressInfos(infos, &count); if (error != B_OK) RETURN_ERROR(error); // check and relocate the addresses for (int32 i = 0; i < count; i++) { // check Address* address = infos[i].address; int32 size = address->GetSize(); int32 offset = address->GetOffset(); //PRINT((" relocating address: area: %ld, offset: %ld, size: %ld...\n", //address->GetArea(), offset, size)); if (offset < 0 || size < 0 || size > infos[i].max_size) RETURN_ERROR(B_BAD_DATA); if ((infos[i].flags & ADDRESS_NOT_NULL) && size == 0) RETURN_ERROR(B_BAD_DATA); // relocate area_id area = address->GetArea(); if (area < 0) { // data in the buffer itself if (offset == 0 && size == 0) { //PRINT((" -> relocated address: NULL\n")); address->SetRelocatedAddress(NULL); } else { if (offset < (int32)sizeof(R) || offset + size > fRequestBufferSize) { RETURN_ERROR(B_BAD_DATA); } //PRINT((" -> relocated address: %p\n", (uint8*)request + offset)); address->SetRelocatedAddress((uint8*)request + offset); } } else { // clone the area void* data; area = clone_area("cloned request data", &data, #ifdef _KERNEL_MODE B_ANY_KERNEL_ADDRESS, #else B_ANY_ADDRESS, #endif B_READ_AREA, area); if (area < 0) RETURN_ERROR(area); fAreas[(*fAreaCount)++] = area; // check offset and size area_info areaInfo; error = get_area_info(area, &areaInfo); if (error != B_OK) RETURN_ERROR(error); if (offset + size > (int32)areaInfo.size) RETURN_ERROR(B_BAD_DATA); //PRINT((" -> relocated address: %p\n", (uint8*)data + offset)); address->SetRelocatedAddress((uint8*)data + offset); } } // finally let the request check its integrity error = request->Check(); if (error != B_OK) RETURN_ERROR(error); fSuccess = true; //PRINT(("RequestRelocator done: success\n")); return B_OK; }
status_t _user_system_profiler_start(struct system_profiler_parameters* userParameters) { // copy params to the kernel struct system_profiler_parameters parameters; if (userParameters == NULL || !IS_USER_ADDRESS(userParameters) || user_memcpy(¶meters, userParameters, sizeof(parameters)) != B_OK) { return B_BAD_ADDRESS; } // check the parameters team_id team = thread_get_current_thread()->team->id; area_info areaInfo; status_t error = get_area_info(parameters.buffer_area, &areaInfo); if (error != B_OK) return error; if (areaInfo.team != team) return B_BAD_VALUE; if ((parameters.flags & B_SYSTEM_PROFILER_SAMPLING_EVENTS) != 0) { if (parameters.stack_depth < 1) return B_BAD_VALUE; if (parameters.interval < B_DEBUG_MIN_PROFILE_INTERVAL) parameters.interval = B_DEBUG_MIN_PROFILE_INTERVAL; if (parameters.stack_depth > B_DEBUG_STACK_TRACE_DEPTH) parameters.stack_depth = B_DEBUG_STACK_TRACE_DEPTH; } // quick check to see whether we do already have a profiler installed InterruptsSpinLocker locker(sProfilerLock); if (sProfiler != NULL) return B_BUSY; locker.Unlock(); // initialize the profiler SystemProfiler* profiler = new(std::nothrow) SystemProfiler(team, areaInfo, parameters); if (profiler == NULL) return B_NO_MEMORY; ObjectDeleter<SystemProfiler> profilerDeleter(profiler); error = profiler->Init(); if (error != B_OK) return error; // set the new profiler locker.Lock(); if (sProfiler != NULL) return B_BUSY; profilerDeleter.Detach(); sProfiler = profiler; locker.Unlock(); return B_OK; }
status_t start_system_profiler(size_t areaSize, uint32 stackDepth, bigtime_t interval) { struct ParameterDeleter { ParameterDeleter(area_id area) : fArea(area), fDetached(false) { } ~ParameterDeleter() { if (!fDetached) { delete_area(fArea); delete sRecordedParameters; sRecordedParameters = NULL; } } void Detach() { fDetached = true; } private: area_id fArea; bool fDetached; }; void* address; area_id area = create_area("kernel profile data", &address, B_ANY_KERNEL_ADDRESS, areaSize, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); if (area < 0) return area; ParameterDeleter parameterDeleter(area); sRecordedParameters = new(std::nothrow) system_profiler_parameters; if (sRecordedParameters == NULL) return B_NO_MEMORY; sRecordedParameters->buffer_area = area; sRecordedParameters->flags = B_SYSTEM_PROFILER_TEAM_EVENTS | B_SYSTEM_PROFILER_THREAD_EVENTS | B_SYSTEM_PROFILER_IMAGE_EVENTS | B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS | B_SYSTEM_PROFILER_SAMPLING_EVENTS; sRecordedParameters->locking_lookup_size = 4096; sRecordedParameters->interval = interval; sRecordedParameters->stack_depth = stackDepth; area_info areaInfo; get_area_info(area, &areaInfo); // initialize the profiler SystemProfiler* profiler = new(std::nothrow) SystemProfiler(B_SYSTEM_TEAM, areaInfo, *sRecordedParameters); if (profiler == NULL) return B_NO_MEMORY; ObjectDeleter<SystemProfiler> profilerDeleter(profiler); status_t error = profiler->Init(); if (error != B_OK) return error; // set the new profiler InterruptsSpinLocker locker(sProfilerLock); if (sProfiler != NULL) return B_BUSY; parameterDeleter.Detach(); profilerDeleter.Detach(); sProfiler = profiler; locker.Unlock(); return B_OK; }
status_t VideoConsumer::CreateBuffers(const media_format& format) { FUNCTION("VideoConsumer::CreateBuffers\n"); // delete any old buffers DeleteBuffers(); status_t status = B_OK; // create a buffer group uint32 width = format.u.raw_video.display.line_width; uint32 height = format.u.raw_video.display.line_count; color_space colorSpace = format.u.raw_video.display.format; PROGRESS("VideoConsumer::CreateBuffers - Width = %ld - Height = %ld - " "Colorspace = %d\n", width, height, colorSpace); fBuffers = new BBufferGroup(); status = fBuffers->InitCheck(); if (B_OK != status) { ERROR("VideoConsumer::CreateBuffers - ERROR CREATING BUFFER GROUP\n"); return status; } // and attach the bitmaps to the buffer group BRect bounds(0, 0, width - 1, height - 1); for (uint32 i = 0; i < kBufferCount; i++) { // figure out the bitmap creation flags uint32 bitmapFlags = 0; if (fTryOverlay) { // try to use hardware overlay bitmapFlags |= B_BITMAP_WILL_OVERLAY; if (i == 0) bitmapFlags |= B_BITMAP_RESERVE_OVERLAY_CHANNEL; } else bitmapFlags = B_BITMAP_IS_LOCKED; fBitmap[i] = new BBitmap(bounds, bitmapFlags, colorSpace); status = fBitmap[i]->InitCheck(); if (status >= B_OK) { buffer_clone_info info; uint8* bits = (uint8*)fBitmap[i]->Bits(); info.area = area_for(bits); area_info bitmapAreaInfo; status = get_area_info(info.area, &bitmapAreaInfo); if (status != B_OK) { fprintf(stderr, "VideoConsumer::CreateBuffers() - " "get_area_info(): %s\n", strerror(status)); return status; } //printf("area info for bitmap %ld (%p):\n", i, fBitmap[i]->Bits()); //printf(" area: %ld\n", bitmapAreaInfo.area); //printf(" size: %ld\n", bitmapAreaInfo.size); //printf(" lock: %ld\n", bitmapAreaInfo.lock); //printf(" protection: %ld\n", bitmapAreaInfo.protection); //printf(" ram size: %ld\n", bitmapAreaInfo.ram_size); //printf(" copy_count: %ld\n", bitmapAreaInfo.copy_count); //printf(" out_count: %ld\n", bitmapAreaInfo.out_count); //printf(" address: %p\n", bitmapAreaInfo.address); info.offset = bits - (uint8*)bitmapAreaInfo.address; info.size = (size_t)fBitmap[i]->BitsLength(); info.flags = 0; info.buffer = 0; // the media buffer id BBuffer* buffer = NULL; if ((status = fBuffers->AddBuffer(info, &buffer)) != B_OK) { ERROR("VideoConsumer::CreateBuffers - ERROR ADDING BUFFER " "TO GROUP (%ld): %s\n", i, strerror(status)); return status; } else { PROGRESS("VideoConsumer::CreateBuffers - SUCCESSFUL ADD " "BUFFER TO GROUP\n"); } fBufferMap[i] = buffer; } else { ERROR("VideoConsumer::CreateBuffers - ERROR CREATING VIDEO RING " "BUFFER (Index %ld Width %ld Height %ld Colorspace %d: %s\n", i, width, height, colorSpace, strerror(status)); return status; } } FUNCTION("VideoConsumer::CreateBuffers - EXIT\n"); return status; }
static status_t init_ring_buffers(dp83815_properties_t *data) { uint32 i; area_info info; physical_entry map[2]; uint32 pages; descriptor_t *RxDescRing = NULL; descriptor_t *TxDescRing = NULL; descriptor_t *desc_base_virt_addr; uint32 desc_base_phys_addr; void *buff_base_virt_addr; uint32 buff_base_phys_addr; data->mem_area = 0; #define NUM_BUFFS 2*MAX_DESC pages = pages_needed(2*MAX_DESC*sizeof(descriptor_t) + NUM_BUFFS*BUFFER_SIZE); data->mem_area = create_area(kDevName " desc buffer", (void**)&RxDescRing, B_ANY_KERNEL_ADDRESS, pages * B_PAGE_SIZE, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); if( data->mem_area < 0 ) return -1; get_area_info(data->mem_area, &info); get_memory_map(info.address, info.size, map, 4); desc_base_phys_addr = (int)map[0].address + NUM_BUFFS*BUFFER_SIZE; desc_base_virt_addr = (info.address + NUM_BUFFS*BUFFER_SIZE); buff_base_phys_addr = (int)map[0].address; buff_base_virt_addr = info.address; RxDescRing = desc_base_virt_addr; for( i = 0; i < MAX_DESC; i++ ) { RxDescRing[i].link = desc_base_phys_addr + ((i+1)%MAX_DESC)*sizeof(descriptor_t); RxDescRing[i].cmd = MAX_PACKET_SIZE; RxDescRing[i].ptr = buff_base_phys_addr +i*BUFFER_SIZE; RxDescRing[i].virt_next = &RxDescRing[(i+1)%MAX_DESC]; RxDescRing[i].virt_buff = buff_base_virt_addr + i*BUFFER_SIZE; } TxDescRing = desc_base_virt_addr + MAX_DESC; for( i = 0; i < MAX_DESC; i++ ) { TxDescRing[i].link = desc_base_phys_addr + MAX_DESC*sizeof(descriptor_t)+ ((i+1)%MAX_DESC)*sizeof(descriptor_t); TxDescRing[i].cmd = MAX_PACKET_SIZE; TxDescRing[i].ptr = buff_base_phys_addr + ((i+MAX_DESC)*BUFFER_SIZE); TxDescRing[i].virt_next = &TxDescRing[(i+1)%MAX_DESC]; TxDescRing[i].virt_buff = buff_base_virt_addr + ((i+MAX_DESC)*BUFFER_SIZE); } data->Rx.Curr = RxDescRing; data->Tx.Curr = TxDescRing; data->Rx.CurrInt = RxDescRing; data->Tx.CurrInt = TxDescRing; write32(REG_RXDP, desc_base_phys_addr); /* set the initial rx descriptor */ i = desc_base_phys_addr+MAX_DESC*sizeof(descriptor_t); write32(REG_TXDP, i); /* set the initial tx descriptor */ return B_OK; }
status_t iw_find_low_memory(interwave_dev * iw) { size_t low_size = (MIN_MEMORY_SIZE+(B_PAGE_SIZE-1))&~(B_PAGE_SIZE-1); size_t allocate_size; physical_entry where; uint32 boundary; size_t trysize; area_id curarea; void * addr; char name[DEVNAME]; if (low_size < MIN_MEMORY_SIZE) { low_size = MIN_MEMORY_SIZE; } if (low_size > 65536) { iwprintf("too much low memory requested !"); low_size = 65536; } allocate_size = 2*low_size; sprintf(name, "%s_low", iw->name); curarea = find_area(name); if (curarea >= 0) { /* area there from previous run */ area_info ainfo; iwprintf("testing likely candidate..."); if (get_area_info(curarea, &ainfo)) { iwprintf("no info"); goto allocate; } /* test area we found */ trysize = ainfo.size; addr = ainfo.address; if (trysize < allocate_size) { iwprintf("too small (%x)", trysize); goto allocate; } if (get_memory_map(addr, trysize, &where, 1) < B_OK) { iwprintf("no memory map"); goto allocate; } if ((uint32)where.address & 0xff000000) { iwprintf("bad physical address"); goto allocate; } if (ainfo.lock < B_FULL_LOCK || where.size < allocate_size) { iwprintf("lock not contiguous"); goto allocate; } goto a_o_k; } allocate: if (curarea >= 0) { delete_area(curarea); /* area didn't work */ curarea = -1; } iwprintf("allocating new low area"); trysize = allocate_size; curarea = create_area(name, &addr, B_ANY_KERNEL_ADDRESS, trysize, B_LOMEM, B_READ_AREA | B_WRITE_AREA); iwprintf("create_area(%d) returned area %x at logical 0x%08x", trysize, curarea, addr); if (curarea < 0) { goto oops; } if (get_memory_map(addr, allocate_size, &where, 1) < 0) { delete_area(curarea); curarea = B_ERROR; goto oops; } if ((uint32)where.address & 0xff000000) { // does not start in low memory delete_area(curarea); curarea = B_ERROR; goto oops; } if (((uint32)where.address+allocate_size) & 0xff000000) { // does not end in low memory delete_area(curarea); curarea = B_ERROR; goto oops; } oops: if (curarea < 0) { dprintf("interwave: failed to create low_mem area\n"); return curarea; } a_o_k: iwprintf("successfully found or created low area!"); iwprintf("physical 0x%08x-0x%08x logical 0x%08x size %d", where.address, where.address+trysize-1, addr, trysize); iw->low_size = low_size; iw->low_area = curarea; // The resulting double-sized area probably crosses a 64K boundary. // Let's change the start address so that the final, normal-sized one does not. // The first boundary possibly crossed boundary = ((uint32)where.address & 0xffff0000) + 0x00010000; // The good chunk (low_size bytes not crossing a 64K boundary) may be // either below or above the first boundary. if((boundary-(uint32)where.address) >= low_size) { // it's below, nothing to change iw->low_mem = (uchar *)addr; iw->low_phys = (vuchar *)where.address; iwprintf("current size is %d bytes",trysize); iwprintf("keeping %d bytes",low_size); if(trysize>low_size) resize_area(curarea,low_size); } else { // it's above - bump up start address uint32 delta = boundary - (uint32)where.address; iw->low_mem = (uchar *)addr + delta; iw->low_phys = (vuchar *)boundary; // Unfortunately, what's below the boundary (delta bytes) is wasted. // We can't truncate an area's bottom. iwprintf("current size is %d bytes",trysize); iwprintf("keeping %d bytes, waste=%d",low_size+delta,delta); if(trysize>low_size+delta) resize_area(curarea,low_size+delta); } iwprintf("using physical 0x%08x-0x%08x logical 0x%08x size %d", iw->low_phys, iw->low_phys+iw->low_size-1, iw->low_mem, iw->low_size); return B_OK; }
void beos_startup(int argc, char **argv) { if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster")) { /* * We are in the postmaster, create the protection semaphore for * shared mem remapping */ beos_shm_sem = create_sem(1, "beos_shm_sem"); } if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0) { /* We are in the support server, run it ... */ port_id port_in; port_id port_out; /* Get back port ids from arglist */ sscanf(argv[2], "%d", (int *) (&port_in)); sscanf(argv[3], "%d", (int *) (&port_out)); /* Main server loop */ for (;;) { int32 opcode = 0; char datas[4000]; /* * Wait for a message from the backend : 1 : load a shared object * 2 : unload a shared object any other : exit support server */ read_port(port_in, &opcode, datas, 4000); switch (opcode) { image_id addon; image_info info_im; area_info info_ar; void *fpt; /* Load Add-On */ case 1: /* Load shared object */ addon = load_add_on(datas); /* send back the shared object Id */ write_port(port_out, addon, NULL, 0); /* Get Shared Object infos */ get_image_info(addon, &info_im); /* get text segment info */ get_area_info(area_for(info_im.text), &info_ar); /* Send back area_id of text segment */ write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1); /* Send back real address of text segment */ write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1); /* get data segment info */ get_area_info(area_for(info_im.data), &info_ar); /* Send back area_id of data segment */ write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1); /* Send back real address of data segment */ write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1); break; /* UnLoad Add-On */ case 2: /* * Unload shared object and send back the result of the * operation */ write_port(port_out, unload_add_on(*((int *) (datas))), NULL, 0); break; /* Cleanup and exit */ case 3: /* read image Id on the input port */ read_port(port_in, &addon, NULL, 0); /* Loading symbol */ fpt = NULL; if (get_image_symbol(addon, datas, B_SYMBOL_TYPE_TEXT, &fpt) == B_OK); { /* * Sometime the loader return B_OK for an inexistant * function with an invalid address !!! Check that the * return address is in the image range */ get_image_info(addon, &info_im); if ((fpt < info_im.text) ||(fpt >= (info_im.text +info_im.text_size))) fpt = NULL; } /* Send back fptr of data segment */ write_port(port_out, (int32) (fpt), NULL, 0); break; default: /* Free system resources */ delete_port(port_in); delete_port(port_out); /* Exit */ exit(0); break; } } /* Never be there */ exit(1); } }