static void do_ramp_unlock(KHRN_FMEM_T *fmem)
{
   KHRN_FMEM_TWEAK_T *h;
   uint32_t i;
   VG_RAMP_T *ramp;

   for (h = fmem->ramp.start; h != NULL; h = h->header.next)
   {
      for (i = 1; i <= h->header.count; i++)
      {
         ramp = (VG_RAMP_T *)mem_lock(h[i].ramp.handle);
         mem_unlock(ramp->data);
         mem_unlock(h[i].ramp.handle);
         vg_ramp_unretain(h[i].ramp.handle); /* todo: this locks internally */
         vg_ramp_release(h[i].ramp.handle, h[i].ramp.i);
      }
   }
}
Пример #2
0
void iter_InitSequence(ITER_ID iter_id,VM_ID vm_id,INDEX start,NUM end,NUM step)
{
	iter_object *iter = (iter_object*)mem_lock(iter_id);
	TUPLE_ID seq = obj_CreateTuple(4);
	INT_ID iend = obj_CreateInt(end);
	tuple_SetItem(seq,0,iend);
	INT_ID istep = obj_CreateInt(step);
	tuple_SetItem(seq,1,istep);
	INT_ID ipos = obj_CreateInt(start);
	tuple_SetItem(seq,2,ipos);
	INT_ID istart = obj_CreateInt(start);
	tuple_SetItem(seq,3,istart);
	iter->tag = seq;
	obj_IncRefCount(seq);
	iter->block_stack = 0;
	iter->iter_func = &iter_Sequence;
	mem_unlock(iter_id,1);
}
Пример #3
0
// Execute a nop control list to prove that we have contol.
void testControlLists() {
// First we allocate and map some videocore memory to build our control list in.

  // ask the blob to allocate us 256 bytes with 4k alignment, zero it.
  unsigned int handle = mem_alloc(mbox, 0x100, 0x1000, MEM_FLAG_COHERENT | MEM_FLAG_ZERO);
  if (!handle) {
    printf("Error: Unable to allocate memory");
    return;
  }
  // ask the blob to lock our memory at a single location at give is that address.
  uint32_t bus_addr = mem_lock(mbox, handle); 
  // map that address into our local address space.
  uint8_t *list = (uint8_t*) mapmem(bus_addr, 0x100);

// Now we construct our control list.
  // 255 nops, with a halt somewhere in the middle
  for(int i = 0; i < 0xff; i++) {
    list[i] = 1; // NOP
  }
  list[0xbb] = 0; // Halt.

// And then we setup the v3d pipeline to execute the control list.
  printf("V3D_CT0CS: 0x%08x\n", v3d[V3D_CT0CS]); 
  printf("Start Address: 0x%08x\n", bus_addr);
  // Current Address = start of our list (bus address)
  v3d[V3D_CT0CA] = bus_addr;
  // End Address = just after the end of our list (bus address) 
  // This also starts execution.
  v3d[V3D_CT0EA] = bus_addr + 0x100;
  
  // print status while running
  printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]);

  // Wait a second to be sure the contorl list execution has finished
  while(v3d[V3D_CT0CS] & 0x20);

  // print the status again.
  printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]);

// Release memory;
  unmapmem((void *) list, 0x100);
  mem_unlock(mbox, handle);
  mem_free(mbox, handle);
}
Пример #4
0
char InitDma(void *FunctionTerminate)
{
	//printf("Init DMA\n");
	
	// Catch all signals possible - it is vital we kill the DMA engine
	// on process exit!
	int i;
	for (i = 0; i < 64; i++) {
		struct sigaction sa;

		memset(&sa, 0, sizeof(sa));
		sa.sa_handler = FunctionTerminate;//terminate;
		sigaction(i, &sa, NULL);
	}

	NUM_SAMPLES = NUM_SAMPLES_MAX;

	/* Use the mailbox interface to the VC to ask for physical memory */
	/*unlink(MBFILE);
	if (mknod(MBFILE, S_IFCHR|0600, makedev(100, 0)) < 0)
	{
		printf("Failed to create mailbox device\n");
		return 0;
	}
	*/
	mbox.handle = mbox_open();
	if (mbox.handle < 0)
	{
		printf("Failed to open mailbox\n");
		return(0);
	}
	
	mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES* PAGE_SIZE, PAGE_SIZE, mem_flag);
	/* TODO: How do we know that succeeded? */
	//printf("mem_ref %x\n", mbox.mem_ref);
	mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
	//printf("bus_addr = %x\n", mbox.bus_addr);
	mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES* PAGE_SIZE);
	//printf("virt_addr %p\n", mbox.virt_addr);
	virtbase = (uint32_t *)mbox.virt_addr;
	//printf("virtbase %p\n", virtbase);
	return(1);
	
}
Пример #5
0
OBJECT_ID iter_Iteration(ITER_ID iter_id,VM_ID vm_id)
{
	iter_object *iter = (iter_object*)mem_lock(iter_id);
	TUPLE_ID it = iter->tag;
	mem_unlock(iter_id,0);
	OBJECT_ID next = tuple_GetNextItem(it);
	if(next == 0 || obj_GetType(next) == TYPE_NONE)
	{
		tuple_ResetIteration(it);
		if(next == 0)
		{
			OBJECT_ID r = obj_CreateEmpty(TYPE_NONE);
			obj_IncRefCount(r);
			return(r);
		}
	}
	obj_IncRefCount(next);
	return(next);
}
Пример #6
0
int gpu_fft_alloc(int mb, unsigned size, struct GPU_FFT_PTR *ptr)
{

	struct GPU_FFT_HOST host;
	struct GPU_FFT_BASE *base;
	volatile unsigned *peri;
	unsigned handle;

	if (gpu_fft_get_host_info(&host))
		return -5;

	if (qpu_enable(mb, 1))
		return -1;

	// Shared memory
	handle = mem_alloc(mb, size, 4096, host.mem_flg);
	if (!handle)
	{
		qpu_enable(mb, 0);
		return -3;
	}

	peri = (volatile unsigned *)mapmem(host.peri_addr, host.peri_size);
	if (!peri)
	{
		mem_free(mb, handle);
		qpu_enable(mb, 0);
		return -4;
	}

	ptr->vc = mem_lock(mb, handle);
	ptr->arm.vptr = mapmem(BUS_TO_PHYS(ptr->vc + host.mem_map), size);

	base = (struct GPU_FFT_BASE *)ptr->arm.vptr;
	base->peri = peri;
	base->peri_size = host.peri_size;
	base->mb = mb;
	base->handle = handle;
	base->size = size;

	return 0;
}
Пример #7
0
static void khrn_image_to_native_buffer(KHRN_IMAGE_T *image, android_native_buffer_t *buffer, void *bits)
{
    MEM_HANDLE_T mem_handle;
    uint8_t *ptr;
    int size;

    mem_handle = image->mh_storage;
    ptr = (uint8_t*)mem_lock(mem_handle);
    size = mem_get_size(mem_handle);

    // memcpy(bits, ptr, size);
    {
        /* V3D Y axis calibrarion and that of Android is opposite, so copying from top of src to bottom of dest */
        /* This could be a place where we can look for optimization */
        int image_height, image_stride;
        int buffer_height, buffer_stride;
        int copy_height, copy_stride, i;

        image_height = (uint16_t)(khrn_image_is_packed_mask(image->format) ? khrn_image_get_packed_mask_height(image->height) : image->height);
        image_stride = image->stride;
        buffer_height = buffer->height;
        buffer_stride = buffer->width * bpp;
        copy_height = (image_height <= buffer_height) ? image_height : buffer_height;
        copy_stride = (image_stride <= buffer_stride) ? image_stride : buffer_stride;

#ifndef BCG_FB_LAYOUT
        ptr += (image->offset + size - image_stride);
#endif
        for (i=0; i< copy_height; i++) {
            memcpy(bits, ptr, copy_stride);
            bits = (void *)((char *)bits + buffer_stride);
#ifndef BCG_FB_LAYOUT
            ptr -= image_stride;
#else
            ptr += image_stride;
#endif
        }
    }
}
void egl_disp_ready(EGL_DISP_SLOT_HANDLE_T slot_handle, bool skip)
{
#ifdef BRCM_V3D_OPT
	return;
#endif
   DISP_T *disp = slot_handle_get_disp(slot_handle);
   uint32_t slot = slot_handle_get_slot(slot_handle);

#ifdef EGL_DISP_FPS
   /* todo: this isn't safe when resizing with swap interval 0 */
   MEM_HANDLE_T image_handle = disp->in_use.images[slot & (next_power_of_2(disp->in_use.n) - 1)];
   KHRN_IMAGE_T *image = (KHRN_IMAGE_T *)mem_lock(image_handle);
   fps_put(image, image->width - 4, 4);
   mem_unlock(image_handle);
#endif

   if (skip) {
      disp->in_use.slots[slot].swap_interval = 0;
      disp->in_use.slots[slot].skip = true;
   }
   khrn_barrier();
   disp->in_use.slots[slot].ready = true;
   notify_llat(disp);
}
Пример #9
0
void out_free_page(void *block)
{
        mem_lock();
        in_free_page(block);
        mem_unlock();
}
Пример #10
0
static void resolve_rx_bulks(VCHIQ_STATE_T *state)
{
   VCHIQ_CHANNEL_T *local = state->local;
   VCHIQ_CHANNEL_T *remote = state->remote;
   int retrigger = 0;

   VCHIQ_TRACE("%d: rrb %x %x", state->id, local->bulk.process, local->bulk.insert);
   while (local->bulk.process != local->bulk.insert) {
      VCHIQ_RX_BULK_T *rx_bulk = &local->bulk.bulks[local->bulk.process & (VCHIQ_NUM_CURRENT_BULKS - 1)];
      VCHIQ_SERVICE_T *service;
      VCHIQ_TX_BULK_T *tx_bulk;

      /* Ensure the service isn't being closed */
      if (rx_bulk->dstport < VCHIQ_MAX_SERVICES)
      {
         service = &local->services[rx_bulk->dstport];
         if (service->srvstate == VCHIQ_SRVSTATE_OPEN)
         {
            VCHIQ_SERVICE_T *remote_service = &remote->services[service->remoteport];
            if (remote_service->process == remote_service->insert)
               break; /* No tx bulk - stall */

            tx_bulk = &remote_service->bulks[remote_service->process & (VCHIQ_NUM_SERVICE_BULKS - 1)];

            if (rx_bulk->size == tx_bulk->size)
            {
               const void *tx_data;
               void *rx_data;

#ifdef VCHIQ_VC_SIDE
               vcos_assert(tx_bulk->handle == VCHI_MEM_HANDLE_INVALID);
               tx_data = tx_bulk->data;
#else
               if (tx_bulk->handle == VCHI_MEM_HANDLE_INVALID)
                  tx_data = tx_bulk->data;
               else
               {
                  tx_data = (const char *)mem_lock(tx_bulk->handle) + (int)tx_bulk->data;
                  tx_bulk->data = tx_data; /* Overwrite to avoid an abort */
               }
#endif
               if (rx_bulk->handle == VCHI_MEM_HANDLE_INVALID)
                  rx_data = rx_bulk->data;
               else
               {
                  rx_data = (char *)mem_lock(rx_bulk->handle) + (int)rx_bulk->data;
                  rx_bulk->data = rx_data; /* Overwrite to avoid an abort */
               }

               vchiq_copy_bulk_from_host(rx_data, tx_data, rx_bulk->size);

               if (rx_bulk->handle != VCHI_MEM_HANDLE_INVALID)
                  mem_unlock(rx_bulk->handle);

#ifndef VCHIQ_VC_SIDE
               if (tx_bulk->handle != VCHI_MEM_HANDLE_INVALID)
                  mem_unlock(tx_bulk->handle);
#endif

               VCHIQ_TRACE("%d: rrb %x<->%x(%d)", state->id, local->bulk.process, remote_service->process, service->remoteport);
            }
            else
            {
               /* Abort these non-matching transfers */
               rx_bulk->data = NULL;
               tx_bulk->data = NULL;

               VCHIQ_TRACE("%d: rrb %x<->%x(%d) ABORTED", state->id, local->bulk.process, remote_service->process, service->remoteport);
            }

            remote_service->process++;

            remote_event_signal(&remote->trigger);
         }
         else
         {
            rx_bulk->data = NULL; /* Aborted */
            VCHIQ_TRACE("%d: rrb %x ABORTED", state->id, local->bulk.process);
         }
      }

      local->bulk.process++;

      retrigger = 1;
   }

   if (retrigger)
      remote_event_signal_local(&local->trigger);
}
Пример #11
0
static void resolve_tx_bulks(VCHIQ_STATE_T *state)
{
   VCHIQ_CHANNEL_T *local = state->local;
   VCHIQ_CHANNEL_T *remote = state->remote;
   int retrigger = 0;

   VCHIQ_TRACE("%d: rtb %x %x", state->id, remote->bulk.process, remote->bulk.insert);
   while (remote->bulk.process != remote->bulk.insert) {
      VCHIQ_RX_BULK_T *rx_bulk = &remote->bulk.bulks[remote->bulk.process & (VCHIQ_NUM_CURRENT_BULKS - 1)];
      VCHIQ_SERVICE_T *service;
      VCHIQ_TX_BULK_T *tx_bulk;

      if (VCHIQ_PORT_IS_VALID(rx_bulk->dstport))
      {
         /* Find connected service */
         service = get_connected_service(local, rx_bulk->dstport);

         if (service == NULL)
         {
            rx_bulk->data = NULL; /* Abort */
            VCHIQ_TRACE("%d: rtb %x(%d) ABORTED", state->id, remote->bulk.process, rx_bulk->dstport);
         }
         else
         {
            if (service->process == service->insert)
               break; /* No matching transmit Stall */

            tx_bulk = &service->bulks[service->process & (VCHIQ_NUM_SERVICE_BULKS - 1)];

            if (rx_bulk->size == tx_bulk->size)
            {
               const void *tx_data;

               vcos_assert(rx_bulk->handle == VCHI_MEM_HANDLE_INVALID);

               if (tx_bulk->handle == VCHI_MEM_HANDLE_INVALID)
                  tx_data = tx_bulk->data;
               else
               {
                  tx_data = (const char *)mem_lock(tx_bulk->handle) + (int)tx_bulk->data;
                  tx_bulk->data = tx_data; /* Overwrite to avoid an abort */
               }

               vchiq_copy_bulk_to_host(rx_bulk->data, tx_data, rx_bulk->size);

               if (tx_bulk->handle != VCHI_MEM_HANDLE_INVALID)
                  mem_unlock(tx_bulk->handle);

               VCHIQ_TRACE("%d: rtb %x<->%x(%d)", state->id, service->process, remote->bulk.process, rx_bulk->dstport);
            }
            else
            {
               /* Abort these transfers */
               rx_bulk->data = NULL;
               tx_bulk->data = NULL;

               VCHIQ_TRACE("%d: rtb %x<->%x(%d) ABORTED", state->id, service->process, remote->bulk.process, rx_bulk->dstport);
            }

            retrigger = 1;

            service->process++;
         }
      }

      remote->bulk.process++;

      remote_event_signal(&remote->trigger);
   }

   if (retrigger)
      remote_event_signal_local(&local->trigger);
}
Пример #12
0
OBJECT_ID BinaryOp(OBJECT_ID tos_id,OBJECT_ID tos1_id,unsigned char op)
{
	object *tos = (object*)mem_lock(tos_id);
	object *tos1 = (object*)mem_lock(tos1_id);
	OBJECT_ID new_tos_id = 0;
	if(tos->type == TYPE_UNICODE && tos1->type == TYPE_UNICODE && op == OPCODE_BINARY_ADD) //string add -> returns string
	{
		mem_unlock(tos1_id,0);
		mem_unlock(tos_id,0);
		return(StringAdd(tos1_id,tos_id));
	}
	
	if(tos->type == TYPE_INT && tos1->type == TYPE_UNICODE && op == OPCODE_BINARY_MULTIPLY) //unicode multiply -> returns unicode
	{
		//printf("string multiply\n");
		mem_unlock(tos1_id,0);
		mem_unlock(tos_id,0);
		return(StringMultiply(tos1_id,tos_id));
	}
	if(tos->type == TYPE_INT && tos1->type == TYPE_TUPLE && op == OPCODE_BINARY_MULTIPLY) //tuple multiply -> returns tuple
	{
		NUM a =(NUM) ((int_object*)tos)->value;

		NUM mnum = tuple_GetLen(tos1_id);
		if(mnum == 1)
		{	
			OBJECT_ID old = tos1_id;
			tos1_id = tuple_GetItem(tos1_id,0);
			mem_unlock(old,0);//TODO what if tos1_id == old .... ???????
			tos1 = (object*)mem_lock(tos1_id);
		}
		TUPLE_ID mtr = obj_CreateTuple(a);
		for(NUM i = 0; i < a; i++)
		{
			tuple_SetItem(mtr,i,tos1_id);
		}
		#ifdef USE_DEBUGGING
		if((debug_level & DEBUG_VERBOSE_STEP) > 0)
			obj_Dump(mtr,0,1);
		#endif
		mem_unlock(tos1_id,0);
		mem_unlock(tos_id,0);
		return(mtr);
	}
	if(tos->type == TYPE_BINARY_FLOAT || tos1->type == TYPE_BINARY_FLOAT) //mixed op -> returns float
	{
		FLOAT af = 0.0f;
		FLOAT bf = 0.0f;
		//printf("float ret\n");
		
		if(tos->type == TYPE_INT)
		//if (tos1->type == TYPE_INT)
		{
			af = (FLOAT) ((int_object*)tos)->value;
			//af = (FLOAT) ((int_object*)tos1)->value;
		}	
		if(tos1->type == TYPE_INT)
		//if (tos->type == TYPE_INT)
		{
			bf = (FLOAT) ((int_object*)tos1)->value;
			//bf = (FLOAT) ((int_object*)tos)->value;
		}	
		if(tos->type == TYPE_BINARY_FLOAT)
		//if (tos1->type == TYPE_BINARY_FLOAT)
		{
			af = ((float_object*)tos)->value;
			//af = ((float_object*)tos1)->value;
		}	
		if(tos1->type == TYPE_BINARY_FLOAT)
		//if (tos->type == TYPE_BINARY_FLOAT)
		{
			bf = ((float_object*)tos1)->value;
			//bf = ((float_object*)tos)->value;
		}	
		mem_unlock(tos1_id,0);
		mem_unlock(tos_id,0);
		new_tos_id = obj_CreateFloat(0);
		float_object *new_tos = (float_object*)mem_lock(new_tos_id);
		switch(op)
		{
			case OPCODE_INPLACE_MULTIPLY:
			case OPCODE_BINARY_MULTIPLY:
				{
					new_tos->value = bf  * af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g * %7g = %7g\n", bf, af, bf  * af);
					#endif
				}
				break;
			case OPCODE_INPLACE_OR:
			case OPCODE_BINARY_OR:
				{
					new_tos->value = (long)bf  | (long)af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g | %7g = %7g\n", bf, af, (long)bf  | (long)af);
					#endif
				}
				break;
			case OPCODE_INPLACE_XOR:
			case OPCODE_BINARY_XOR:
				{
					new_tos->value = (long)bf  ^ (long)af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g ^ %7g = %7g\n", bf, af, (long)bf  ^ (long)af);
					#endif
				}
				break;			
			case OPCODE_INPLACE_AND:
			case OPCODE_BINARY_AND:
				{
					new_tos->value = (long)bf  & (long)af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g & %7g = %7g\n", bf, af, (long)bf  & (long)af);
					#endif
				}
				break;
			case OPCODE_INPLACE_LSHIFT:
			case OPCODE_BINARY_LSHIFT:
				{
					new_tos->value = (long)bf << (long)af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g << %7g = %7g\n", bf, af, (long)bf << (long)af);
					#endif
				}
				break;
			case OPCODE_INPLACE_RSHIFT:
			case OPCODE_BINARY_RSHIFT:
				{
					new_tos->value =  (long)bf >>  (long)af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g>> %7g = %7g\n", bf, af,  (long)bf >>  (long)af);
					#endif
				}
				break;
			case OPCODE_INPLACE_MODULO:
			case OPCODE_BINARY_MODULO:
				{
					new_tos->value =  (long)bf %  (long)af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g %% %7g = %7g\n", bf, af,  (long)bf %  (long)af);
					#endif
				}
				break;
			case OPCODE_INPLACE_FLOOR_DIVIDE:
			case OPCODE_BINARY_FLOOR_DIVIDE:
				{
					new_tos->value = floor(bf / af);
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g // %7g = %7g\n", bf, af, floor(bf / af));
					#endif
				}
				break;
			case OPCODE_INPLACE_TRUE_DIVIDE:
			case OPCODE_BINARY_TRUE_DIVIDE:
				{
					new_tos->value = bf / af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g / %7g = %7g\n", bf, af, bf / af);
					#endif
				}
				break;
			case OPCODE_INPLACE_SUBTRACT:
			case OPCODE_BINARY_SUBTRACT:
				{
					new_tos->value = bf-af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g - %7g = %7g\n", bf, af, bf - af);
					#endif
				}
				break;
			case OPCODE_INPLACE_POWER:
			case OPCODE_BINARY_POWER:
				{
					new_tos->value = num_pow(bf, af); //TODO this will most likely not work correctly
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g ** %7g = %7g\n", bf, af, num_pow(bf, af));
					#endif
				}
				break;
			case OPCODE_INPLACE_ADD:
			case OPCODE_BINARY_ADD:
				{
					new_tos->value = bf + af;
					#ifdef USE_DEBUGGING
					debug_printf(DEBUG_VERBOSE_STEP,"%7g + %7g = %7g\n", bf, af, bf + af);
					#endif					
				}
				break;
		}
	}
Пример #13
0
int
main(int argc, char **argv)
{
	parseargs(argc, argv);
	mbox.handle = mbox_open();
	if (mbox.handle < 0)
		fatal("Failed to open mailbox\n");
	unsigned mbox_board_rev = get_board_revision(mbox.handle);
	printf("MBox Board Revision: %#x\n", mbox_board_rev);
	get_model(mbox_board_rev);
	unsigned mbox_dma_channels = get_dma_channels(mbox.handle);
	printf("DMA Channels Info: %#x, using DMA Channel: %d\n", mbox_dma_channels, DMA_CHAN_NUM);

	printf("Using hardware:                 %5s\n", delay_hw == DELAY_VIA_PWM ? "PWM" : "PCM");
	printf("Number of channels:             %5d\n", (int)num_channels);
	printf("PWM frequency:               %5d Hz\n", 1000000/CYCLE_TIME_US);
	printf("PWM steps:                      %5d\n", NUM_SAMPLES);
	printf("Maximum period (100  %%):      %5dus\n", CYCLE_TIME_US);
	printf("Minimum period (%1.3f%%):      %5dus\n", 100.0*SAMPLE_US / CYCLE_TIME_US, SAMPLE_US);
	printf("DMA Base:                  %#010x\n", DMA_BASE);

	setup_sighandlers();

	/* map the registers for all DMA Channels */
	dma_virt_base = map_peripheral(DMA_BASE, (DMA_CHAN_SIZE * (DMA_CHAN_MAX + 1)));
	/* set dma_reg to point to the DMA Channel we are using */
	dma_reg = dma_virt_base + DMA_CHAN_NUM * (DMA_CHAN_SIZE / sizeof(dma_reg));
	pwm_reg = map_peripheral(PWM_BASE, PWM_LEN);
	pcm_reg = map_peripheral(PCM_BASE, PCM_LEN);
	clk_reg = map_peripheral(CLK_BASE, CLK_LEN);
	gpio_reg = map_peripheral(GPIO_BASE, GPIO_LEN);

	/* Use the mailbox interface to the VC to ask for physical memory */
	mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES * PAGE_SIZE, PAGE_SIZE, mem_flag);
	/* TODO: How do we know that succeeded? */
	dprintf("mem_ref %u\n", mbox.mem_ref);
	mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
	dprintf("bus_addr = %#x\n", mbox.bus_addr);
	mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES * PAGE_SIZE);
	dprintf("virt_addr %p\n", mbox.virt_addr);

	if ((unsigned long)mbox.virt_addr & (PAGE_SIZE-1))
		fatal("pi-blaster: Virtual address is not page aligned\n");

	/* we are done with the mbox */
	mbox_close(mbox.handle);
	mbox.handle = -1;
	
	//fatal("TempFatal\n");

	init_ctrl_data();
	init_hardware();
	init_channel_pwm();
	// Init pin2gpio array with 0/false values to avoid locking all of them as PWM.
	init_pin2gpio();
	// Only calls update_pwm after ctrl_data calculates the pin mask to unlock all pins on start.
	init_pwm();
	unlink(DEVFILE);
	if (mkfifo(DEVFILE, 0666) < 0)
		fatal("pi-blaster: Failed to create %s: %m\n", DEVFILE);
	if (chmod(DEVFILE, 0666) < 0)
		fatal("pi-blaster: Failed to set permissions on %s: %m\n", DEVFILE);

	printf("Initialised, ");
	if (daemonize) {
		if (daemon(0,1) < 0) 
			fatal("pi-blaster: Failed to daemonize process: %m\n");
		else
			printf("Daemonized, ");
	}
	printf("Reading %s.\n", DEVFILE);

	go_go_go();

	return 0;
}
Пример #14
0
/**
 * Allocate and initialize memory, buffers, pages, PWM, DMA, and GPIO.
 *
 * @param    ws2811  ws2811 instance pointer.
 *
 * @returns  0 on success, -1 otherwise.
 */
int ws2811_init(ws2811_t *ws2811)
{
    ws2811_device_t *device = NULL;
    int chan;

    // Zero mbox; non-zero values indicate action needed on cleanup
    memset(&mbox, 0, sizeof(mbox));

    ws2811->device = malloc(sizeof(*ws2811->device));
    if (!ws2811->device)
    {
        return -1;
    }
    device = ws2811->device;

    // Determine how much physical memory we need for DMA
    mbox.size = PWM_BYTE_COUNT(max_channel_led_count(ws2811), ws2811->freq) +
               + sizeof(dma_cb_t);
    // Round up to page size multiple
    mbox.size = (mbox.size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);

    // Use the mailbox interface to request memory from the VideoCore
    // We specifiy (-1) for the handle rather than calling mbox_open()
    // so multiple users can share the resource.
    mbox.handle = -1; // mbox_open();
    mbox.mem_ref = mem_alloc(mbox.handle, mbox.size, PAGE_SIZE,
            board_info_sdram_address() == 0x40000000 ? 0xC : 0x4);
    if (mbox.mem_ref == (unsigned) ~0)
    {
       return -1;
    }
    mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
    if (mbox.bus_addr == (unsigned) ~0)
    {
       mem_free(mbox.handle, mbox.size);
       return -1;
    }
    mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), mbox.size);

    // Initialize all pointers to NULL.  Any non-NULL pointers will be freed on cleanup.
    device->pwm_raw = NULL;
    device->dma_cb = NULL;
    for (chan = 0; chan < RPI_PWM_CHANNELS; chan++)
    {
        ws2811->channel[chan].leds = NULL;
    }

    // Allocate the LED buffers
    for (chan = 0; chan < RPI_PWM_CHANNELS; chan++)
    {
        ws2811_channel_t *channel = &ws2811->channel[chan];

        channel->leds = malloc(sizeof(ws2811_led_t) * channel->count);
        if (!channel->leds)
        {
            goto err;
        }

        memset(channel->leds, 0, sizeof(ws2811_led_t) * channel->count);
    }

    device->dma_cb = (dma_cb_t *)mbox.virt_addr;
    device->pwm_raw = (uint8_t *)mbox.virt_addr + sizeof(dma_cb_t);

    pwm_raw_init(ws2811);

    memset((dma_cb_t *)device->dma_cb, 0, sizeof(dma_cb_t));

    // Cache the DMA control block bus address
    device->dma_cb_addr = addr_to_bus(device->dma_cb);

    // Map the physical registers into userspace
    if (map_registers(ws2811))
    {
        goto err;
    }

    // Initialize the GPIO pins
    if (gpio_init(ws2811))
    {
        unmap_registers(ws2811);
        goto err;
    }

    // Setup the PWM, clocks, and DMA
    if (setup_pwm(ws2811))
    {
        unmap_registers(ws2811);
        goto err;
    }

    return 0;

err:
    ws2811_cleanup(ws2811);

    return -1;
}
Пример #15
0
// Render a single triangle to memory.
void testTriangle() {
// Like above, we allocate/lock/map some videocore memory
  // I'm just shoving everything in a single buffer because I'm lazy
  // 8Mb, 4k alignment
  unsigned int handle = mem_alloc(mbox, 0x800000, 0x1000, MEM_FLAG_COHERENT | MEM_FLAG_ZERO);
  if (!handle) {
    printf("Error: Unable to allocate memory");
    return;
  }
  uint32_t bus_addr = mem_lock(mbox, handle); 
  uint8_t *list = (uint8_t*) mapmem(bus_addr, 0x800000);

  uint8_t *p = list;

// Configuration stuff
  // Tile Binning Configuration.
  //   Tile state data is 48 bytes per tile, I think it can be thrown away
  //   as soon as binning is finished.
  addbyte(&p, 112);
  addword(&p, bus_addr + 0x6200); // tile allocation memory address
  addword(&p, 0x8000); // tile allocation memory size
  addword(&p, bus_addr + 0x100); // Tile state data address
  addbyte(&p, 30); // 1920/64
  addbyte(&p, 17); // 1080/64 (16.875)
  addbyte(&p, 0x04); // config

  // Start tile binning.
  addbyte(&p, 6);

  // Primitive type
  addbyte(&p, 56);
  addbyte(&p, 0x32); // 16 bit triangle

  // Clip Window
  addbyte(&p, 102);
  addshort(&p, 0);
  addshort(&p, 0);
  addshort(&p, 1920); // width
  addshort(&p, 1080); // height

  // State
  addbyte(&p, 96);
  addbyte(&p, 0x03); // enable both foward and back facing polygons
  addbyte(&p, 0x00); // depth testing disabled
  addbyte(&p, 0x02); // enable early depth write

  // Viewport offset
  addbyte(&p, 103);
  addshort(&p, 0);
  addshort(&p, 0);

// The triangle
  // No Vertex Shader state (takes pre-transformed vertexes, 
  // so we don't have to supply a working coordinate shader to test the binner.
  addbyte(&p, 65);
  addword(&p, bus_addr + 0x80); // Shader Record

  // primitive index list
  addbyte(&p, 32);
  addbyte(&p, 0x04); // 8bit index, trinagles
  addword(&p, 3); // Length
  addword(&p, bus_addr + 0x70); // address
  addword(&p, 2); // Maximum index

// End of bin list
  // Flush
  addbyte(&p, 5);
  // Nop
  addbyte(&p, 1);
  // Halt
  addbyte(&p, 0);

  int length = p - list;
  assert(length < 0x80);

// Shader Record
  p = list + 0x80;
  addbyte(&p, 0x01); // flags
  addbyte(&p, 6*4); // stride
  addbyte(&p, 0xcc); // num uniforms (not used)
  addbyte(&p, 3); // num varyings
  addword(&p, bus_addr + 0xfe00); // Fragment shader code
  addword(&p, bus_addr + 0xff00); // Fragment shader uniforms
  addword(&p, bus_addr + 0xa0); // Vertex Data

// Vertex Data
  p = list + 0xa0;
  // Vertex: Top, red
  addshort(&p, (1920/2) << 4); // X in 12.4 fixed point
  addshort(&p, 200 << 4); // Y in 12.4 fixed point
  addfloat(&p, 1.0f); // Z
  addfloat(&p, 1.0f); // 1/W
  addfloat(&p, 1.0f); // Varying 0 (Red)
  addfloat(&p, 0.0f); // Varying 1 (Green)
  addfloat(&p, 0.0f); // Varying 2 (Blue)

  // Vertex: bottom left, Green
  addshort(&p, 560 << 4); // X in 12.4 fixed point
  addshort(&p, 800 << 4); // Y in 12.4 fixed point
  addfloat(&p, 1.0f); // Z
  addfloat(&p, 1.0f); // 1/W
  addfloat(&p, 0.0f); // Varying 0 (Red)
  addfloat(&p, 1.0f); // Varying 1 (Green)
  addfloat(&p, 0.0f); // Varying 2 (Blue)

  // Vertex: bottom right, Blue
  addshort(&p, 1360 << 4); // X in 12.4 fixed point
  addshort(&p, 800 << 4); // Y in 12.4 fixed point
  addfloat(&p, 1.0f); // Z
  addfloat(&p, 1.0f); // 1/W
  addfloat(&p, 0.0f); // Varying 0 (Red)
  addfloat(&p, 0.0f); // Varying 1 (Green)
  addfloat(&p, 1.0f); // Varying 2 (Blue)

// Vertex list
  p = list + 0x70;
  addbyte(&p, 0); // top
  addbyte(&p, 1); // bottom left
  addbyte(&p, 2); // bottom right

// fragment shader
  p = list + 0xfe00;
  addword(&p, 0x958e0dbf);
  addword(&p, 0xd1724823); /* mov r0, vary; mov r3.8d, 1.0 */
  addword(&p, 0x818e7176); 
  addword(&p, 0x40024821); /* fadd r0, r0, r5; mov r1, vary */
  addword(&p, 0x818e7376); 
  addword(&p, 0x10024862); /* fadd r1, r1, r5; mov r2, vary */
  addword(&p, 0x819e7540); 
  addword(&p, 0x114248a3); /* fadd r2, r2, r5; mov r3.8a, r0 */
  addword(&p, 0x809e7009); 
  addword(&p, 0x115049e3); /* nop; mov r3.8b, r1 */
  addword(&p, 0x809e7012); 
  addword(&p, 0x116049e3); /* nop; mov r3.8c, r2 */
  addword(&p, 0x159e76c0); 
  addword(&p, 0x30020ba7); /* mov tlbc, r3; nop; thrend */
  addword(&p, 0x009e7000);
  addword(&p, 0x100009e7); /* nop; nop; nop */
  addword(&p, 0x009e7000);
  addword(&p, 0x500009e7); /* nop; nop; sbdone */

// Render control list
  p = list + 0xe200;

  // Clear color
  addbyte(&p, 114);
  addword(&p, 0xff000000); // Opaque Black
  addword(&p, 0xff000000); // 32 bit clear colours need to be repeated twice
  addword(&p, 0);
  addbyte(&p, 0);

  // Tile Rendering Mode Configuration
  addbyte(&p, 113);
  addword(&p, bus_addr + 0x10000); // framebuffer addresss
  addshort(&p, 1920); // width
  addshort(&p, 1080); // height
  addbyte(&p, 0x04); // framebuffer mode (linear rgba8888)
  addbyte(&p, 0x00);

  // Do a store of the first tile to force the tile buffer to be cleared
  // Tile Coordinates
  addbyte(&p, 115);
  addbyte(&p, 0);
  addbyte(&p, 0);
  // Store Tile Buffer General
  addbyte(&p, 28);
  addshort(&p, 0); // Store nothing (just clear)
  addword(&p, 0); // no address is needed

  // Link all binned lists together
  for(int x = 0; x < 30; x++) {
    for(int y = 0; y < 17; y++) {

      // Tile Coordinates
      addbyte(&p, 115);
      addbyte(&p, x);
      addbyte(&p, y);
      
      // Call Tile sublist
      addbyte(&p, 17);
      addword(&p, bus_addr + 0x6200 + (y * 30 + x) * 32);

      // Last tile needs a special store instruction
      if(x == 29 && y == 16) {
        // Store resolved tile color buffer and signal end of frame
        addbyte(&p, 25);
      } else {
        // Store resolved tile color buffer
        addbyte(&p, 24);
      }
    }
  }

  int render_length = p - (list + 0xe200);


// Run our control list
  printf("Binner control list constructed\n");
  printf("Start Address: 0x%08x, length: 0x%x\n", bus_addr, length);

  v3d[V3D_CT0CA] = bus_addr;
  v3d[V3D_CT0EA] = bus_addr + length;
  printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]);

  // Wait for control list to execute
  while(v3d[V3D_CT0CS] & 0x20);
  
  printf("V3D_CT0CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT0CS], v3d[V3D_CT0CA]);
  printf("V3D_CT1CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]);


  v3d[V3D_CT1CA] = bus_addr + 0xe200;
  v3d[V3D_CT1EA] = bus_addr + 0xe200 + render_length;

  while(v3d[V3D_CT1CS] & 0x20);
  
  printf("V3D_CT1CS: 0x%08x, Address: 0x%08x\n", v3d[V3D_CT1CS], v3d[V3D_CT1CA]);
  v3d[V3D_CT1CS] = 0x20;

  // just dump the frame to a file
  FILE *f = fopen("frame.data", "w");
  fwrite(list + 0x10000, (1920*1080*4), 1, f);
  fclose(f);
  printf("frame buffer memory dumpped to frame.data\n");

// Release resources
  unmapmem((void *) list, 0x800000);
  mem_unlock(mbox, handle);
  mem_free(mbox, handle);
}
Пример #16
0
/**
 * create/open a table
 *
 * b0 = ON for non-memory file (file is created by the user, so, it must exists in disk)
 * b1 = ON for create always (truncate if it is exists); FALSE for open if exists or create if it does not exists
 */
dbt_t dbt_create(const char *fileName, int flags) {
  int i, t = -1;

  if (opt_usevmt) {
    flags |= 1;
  }

  // find a free VMT
  for (i = 0; i < MAX_VMT_FILES; i++) {
    if (vmt[i].used == 0) {
      t = i;
      vmt[t].sign = (intptr_t) "VMTH";
      vmt[t].ver = 1;
      vmt[t].flags = flags;
      vmt[t].count = 0;
      vmt[t].size = 0;
      break;
    }
  }
  if (t == -1)                  // no vmt handle free
    return -1;

  // create the table
  if (flags & 1) {
    // VMT: use file
    char fullfile[OS_PATHNAME_SIZE];
    int f_handle, i_handle;

    // open database
    strcpy(vmt[t].base, fileName);
    sprintf(fullfile, "%s.dbt", vmt[t].base);
    vmt[t].f_handle = f_handle = open(fullfile, O_RDWR | O_BINARY);

    if ((flags & 0x2) || vmt[t].f_handle == -1) { // create always
      vmt[t].f_handle = f_handle = open(fullfile, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0660);

      // create index
      sprintf(fullfile, "%s.dbi", vmt[t].base);
      vmt[t].i_handle = i_handle = open(fullfile, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0660);
    } else {
      // open index
      sprintf(fullfile, "%s.dbi", vmt[t].base);
      vmt[t].i_handle = i_handle = open(fullfile, O_RDWR | O_BINARY);
      dbt_file_read_header(t);
    }

    vmt[t].f_handle = f_handle;
    vmt[t].i_handle = i_handle;
    vmt[t].used = 1;

    if (flags & 4)
      vmt[t].count = 0;
    dbt_file_write_header(t);
  } else {
    // VMT: use memory
    int i;

    // preallocate some records
    vmt[t].size = MEM_VMT_GROWSIZE;
    vmt[t].m_handle = mem_alloc(sizeof(mem_t) * vmt[t].size);

    // reset new data
    vmt[t].m_table = (mem_t *)mem_lock(vmt[t].m_handle);
    for (i = 0; i < vmt[t].size; i++) {
      vmt[t].m_table[i] = 0;    // make them NULL
    }

    // 
    vmt[t].used = 1;
  }

  return t;                     // return vmt-handle
}
Пример #17
0
char InitDma(void *FunctionTerminate)
{
    DMA_CHANNEL=4;
    if (system("rm -f linuxversion.txt") != 0) {
        fprintf(stderr, "rm failed\n");
    }
    if (system("uname -r >> linuxversion.txt") != 0) {
        fprintf(stderr, "uname failed\n");
    }
    char *line = NULL;
    size_t size;
//	int fLinux=open("Flinuxversion.txt", "r');
    FILE * flinux=fopen("linuxversion.txt", "r");
    if (getline(&line, &size, flinux) == -1)
    {
        printf("Could no get Linux version\n");
    }
    else
    {
        if(line[0]=='3')
        {
            printf("Wheezy\n");
            DMA_CHANNEL=DMA_CHANNEL_WHEEZY;
        }

        if(line[0]=='4')
        {
            printf("Jessie\n");
            DMA_CHANNEL=DMA_CHANNEL_JESSIE;
        }

    }
    //printf("Init DMA\n");

    // Catch all signals possible - it is vital we kill the DMA engine
    // on process exit!
    int i;
    for (i = 0; i < 64; i++) {
        struct sigaction sa;

        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = FunctionTerminate;//terminate;
        sigaction(i, &sa, NULL);
    }

    //NUM_SAMPLES = NUM_SAMPLES_MAX;

    /* Use the mailbox interface to the VC to ask for physical memory */
    /*
    unlink(MBFILE);
    if (mknod(MBFILE, S_IFCHR|0600, makedev(100, 0)) < 0)
    {
    	printf("Failed to create mailbox device\n");
    	return 0;
    }*/
    mbox.handle = mbox_open();
    if (mbox.handle < 0)
    {
        printf("Failed to open mailbox\n");
        return(0);
    }
    mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES* PAGE_SIZE, PAGE_SIZE, mem_flag);
    /* TODO: How do we know that succeeded? */
    //printf("mem_ref %x\n", mbox.mem_ref);
    mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref);
    //printf("bus_addr = %x\n", mbox.bus_addr);
    mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES* PAGE_SIZE);
    //printf("virt_addr %p\n", mbox.virt_addr);
    virtbase = (uint8_t *)((uint32_t *)mbox.virt_addr);
    //printf("virtbase %p\n", virtbase);
    return(1);

}
Пример #18
0
void out_add_free(void *block, oskit_size_t size)
{
        mem_lock();
        in_add_free(block,size);
        mem_unlock();
}
Пример #19
0
/* Only available if debugging turned on.  */
void out_dump(void)
{
        mem_lock();
        in_dump();
        mem_unlock();
}
Пример #20
0
/**
 * Allocate and initialize memory, buffers, pages, PWM, DMA, and GPIO.
 *
 * @param    ws2811  ws2811 instance pointer.
 *
 * @returns  0 on success, -1 otherwise.
 */
int ws2811_init(ws2811_t *ws2811)
{
    ws2811_device_t *device;
    const rpi_hw_t *rpi_hw;
    int chan;

    ws2811->rpi_hw = rpi_hw_detect();
    if (!ws2811->rpi_hw)
    {
        return -1;
    }
    rpi_hw = ws2811->rpi_hw;

    ws2811->device = malloc(sizeof(*ws2811->device));
    if (!ws2811->device)
    {
        return -1;
    }
    device = ws2811->device;

    // Determine how much physical memory we need for DMA
    device->mbox.size = PWM_BYTE_COUNT(max_channel_led_count(ws2811), ws2811->freq) +
                        sizeof(dma_cb_t);
    // Round up to page size multiple
    device->mbox.size = (device->mbox.size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);

    device->mbox.handle = mbox_open();
    if (device->mbox.handle == -1)
    {
        return -1;
    }

    device->mbox.mem_ref = mem_alloc(device->mbox.handle, device->mbox.size, PAGE_SIZE,
                                     rpi_hw->videocore_base == 0x40000000 ? 0xC : 0x4);
    if (device->mbox.mem_ref == 0)
    {
       return -1;
    }

    device->mbox.bus_addr = mem_lock(device->mbox.handle, device->mbox.mem_ref);
    if (device->mbox.bus_addr == (uint32_t) ~0UL)
    {
       mem_free(device->mbox.handle, device->mbox.size);
       return -1;
    }
    device->mbox.virt_addr = mapmem(BUS_TO_PHYS(device->mbox.bus_addr), device->mbox.size);

    // Initialize all pointers to NULL.  Any non-NULL pointers will be freed on cleanup.
    device->pwm_raw = NULL;
    device->dma_cb = NULL;
    for (chan = 0; chan < RPI_PWM_CHANNELS; chan++)
    {
        ws2811->channel[chan].leds = NULL;
    }

    // Allocate the LED buffers
    for (chan = 0; chan < RPI_PWM_CHANNELS; chan++)
    {
        ws2811_channel_t *channel = &ws2811->channel[chan];

        channel->leds = malloc(sizeof(ws2811_led_t) * channel->count);
        if (!channel->leds)
        {
            goto err;
        }

        memset(channel->leds, 0, sizeof(ws2811_led_t) * channel->count);

        if (!channel->strip_type)
        {
          channel->strip_type=WS2811_STRIP_RGB;
        }
    }

    device->dma_cb = (dma_cb_t *)device->mbox.virt_addr;
    device->pwm_raw = (uint8_t *)device->mbox.virt_addr + sizeof(dma_cb_t);

    pwm_raw_init(ws2811);

    memset((dma_cb_t *)device->dma_cb, 0, sizeof(dma_cb_t));

    // Cache the DMA control block bus address
    device->dma_cb_addr = addr_to_bus(device, device->dma_cb);

    // Map the physical registers into userspace
    if (map_registers(ws2811))
    {
        goto err;
    }

    // Initialize the GPIO pins
    if (gpio_init(ws2811))
    {
        unmap_registers(ws2811);
        goto err;
    }

    // Setup the PWM, clocks, and DMA
    if (setup_pwm(ws2811))
    {
        unmap_registers(ws2811);
        goto err;
    }

    return 0;

err:
    ws2811_cleanup(ws2811);

    return -1;
}
Пример #21
0
HI_VOID* HI_REALLOC(HI_U32 u32ModuleID, HI_VOID *pMemAddr, HI_U32 u32Size)
{
    HI_VOID* pNewMemAddr = NULL;

#ifdef CMN_MMGR_SUPPORT
    struct head *p;
    
    if (NULL != pMemAddr && g_fnModuleCallback)/* when pMemAddr is NULL do malloc.*/
    {
        // Add memory info to MODULE MGR
        if (0 == u32Size)/* when s = 0 realloc() acts like free(). */
        {
            HI_FREE(u32ModuleID, pMemAddr);
        }
        else
        {
            HI_S32 s32Ret = HI_FAILURE;
            
            mem_lock(&g_MemMutex);

            //lookup the module info.
            s32Ret = g_fnModuleCallback(u32ModuleID, MEM_TYPE_USR, 0);
            if(s32Ret != HI_SUCCESS)
            {
                mem_unlock(&g_MemMutex);
                
        	    return NULL;
            }
            
            p = MEM_Find(pMemAddr);
            if (NULL != p)
            {
                pNewMemAddr = realloc(pMemAddr, u32Size);
                if ( NULL != pNewMemAddr)
                {
                    g_fnModuleCallback(u32ModuleID, MEM_TYPE_USR, (-1)*(p->size));

                    MEM_Replace(p, pNewMemAddr, u32Size);
                    
                    g_fnModuleCallback(u32ModuleID, MEM_TYPE_USR, u32Size);

                    mem_unlock(&g_MemMutex);
                    
	                return pNewMemAddr;
                }
            }

            mem_unlock(&g_MemMutex);
        }
    }
    else
    {
        return HI_MALLOC(u32ModuleID, u32Size);
    }
#else
    pNewMemAddr = realloc(pMemAddr, u32Size);
#endif

    return pNewMemAddr;

}
Пример #22
0
/* ----------------------------------------------------------------------
 * the object was allocated from the relocatable mempool; provide a
 * lightweight api call to lock the memory in place before use.
 *
 * returns a pointer to the locked-in-memory data.
 * -------------------------------------------------------------------- */
void *
vc_pool_lock( VC_POOL_OBJECT_T *object )
{
   vcos_assert( object->magic == OBJECT_MAGIC );
   return mem_lock( object->mem );
}
Пример #23
0
int main(int argc, char *argv[]) {

	int mb = mbox_open();

	/* Enable QPU for execution */
	int qpu_enabled = !qpu_enable(mb, 1);
	if (!qpu_enabled) {
		printf("Unable to enable QPU.  Check your firmware is latest.");
		goto cleanup;
	}

	/* Allocate GPU memory and map it into ARM address space */
	unsigned size = 4096;
	unsigned align = 4096;
    	unsigned handle = mem_alloc(mb, size, align, GPU_MEM_FLG);
	if (!handle) {
		printf("Failed to allocate GPU memory.");
		goto cleanup;
	}
	void *gpu_pointer = (void *)mem_lock(mb, handle);
	void *arm_pointer = mapmem((unsigned)gpu_pointer+GPU_MEM_MAP, size);

	unsigned *p = (unsigned *)arm_pointer;

	/*
	   +---------------+ <----+
	   |  QPU Code     |      |
	   |  ...          |      |
	   +---------------+ <--+ |
	   |  Uniforms     |    | |
	   +---------------+    | |
	   |  QPU0 Uniform -----+ |
	   |  QPU0 Start   -------+
	   |  ...                 |
	   |  QPUn Uniform        |
	   |  QPUn PC      -------+
	   +---------------+
	*/

	/* Copy QPU program into GPU memory */
	unsigned *qpu_code = p;
	memcpy(p, program, sizeof program);
	p += (sizeof program)/(sizeof program[0]);

	/* Build Uniforms */
	unsigned *qpu_uniform = p;
	*p++ = 1;
	
	/* Build QPU Launch messages */
	unsigned *qpu_msg = p;
	*p++ = as_gpu_address(qpu_uniform);
	*p++ = as_gpu_address(qpu_code);

	int i;
	for (i=0; i<16+1+2; i++) {
		printf("%08x: %08x\n", gpu_pointer+i*4, ((unsigned *)arm_pointer)[i]);
	}
	printf("qpu exec %08x\n", gpu_pointer + ((void *)qpu_msg - arm_pointer));

	/* Launch QPU program and block till its done */
    	unsigned r = execute_qpu(mb, GPU_QPUS, as_gpu_address(qpu_msg), 1, 10000);
	printf("%d\n", r);

cleanup:
	/* Release GPU memory */
	if (arm_pointer) {
		unmapmem(arm_pointer, size);
	}
    	if (handle) {
		mem_unlock(mb, handle);
    		mem_free(mb, handle);
	}
	
	/* Release QPU */
	if (qpu_enabled) {
	    	qpu_enable(mb, 0);
	}
	
	/* Release mailbox */
	mbox_close(mb);

}
Пример #24
0
void out_stats(void)
{
        mem_lock();
        in_stats();
        mem_unlock();
}
Пример #25
0
static void vc_image_to_RSO_memory(VC_IMAGE_T *image, android_native_buffer_t *buffer, void *bits)
{
    KHRN_IMAGE_FORMAT_T src_format, dst_format;
    KHRN_IMAGE_WRAP_T src, dst;
    uint8_t* src_ptr;
    int conv_width, conv_height;

    dst_format = convert_color_format(buffer->format);

    if (!dst_format)
        return;

    // Swap red and blue. Do t-format conversion if necessary.
    switch (image->type) {
    case VC_IMAGE_TF_RGBA32:
        src_format = ABGR_8888_TF;
        break;
    case VC_IMAGE_TF_RGBX32:
        src_format = XBGR_8888_TF;
        break;
    case VC_IMAGE_TF_RGB565:
        src_format = RGB_565_TF;
        break;
    case VC_IMAGE_TF_RGBA5551:
        src_format = RGBA_5551_TF;
        break;
    case VC_IMAGE_TF_RGBA16:
        src_format = RGBA_4444_TF;
        break;
    case VC_IMAGE_RGBA32:
        src_format = ABGR_8888_RSO;
        break;
    case VC_IMAGE_RGBX32:
        src_format = XBGR_8888_RSO;
        break;
    case VC_IMAGE_RGB565:
        src_format = RGB_565_RSO;
        break;
    default:
        UNREACHABLE();
        src_format = 0;
        break;
    }

    if (!src_format)
        return;

    src_ptr = (image->mem_handle != MEM_INVALID_HANDLE) ? (uint8_t*)mem_lock(image->mem_handle) : (uint8_t*)image->image_data;

    conv_width = (image->width <= buffer->width) ? image->width : buffer->width;
    conv_height = (image->height <= buffer->height) ? image->height : buffer->height;

    khrn_image_wrap(&src, src_format, conv_width, conv_height, image->pitch, src_ptr);
    khrn_image_wrap(&dst, dst_format, conv_width, conv_height, buffer->width * bpp, bits);

    if (src.format == dst.format)
        khrn_image_copy(&dst, &src);
    else
        khrn_image_wrap_convert(&dst, &src, IMAGE_CONV_GL);

    if (image->mem_handle != MEM_INVALID_HANDLE)
        mem_unlock(image->mem_handle);
}
Пример #26
0
void out_remove_free(void *block, oskit_size_t size)
{
        mem_lock();
        in_remove_free(block,size);
        mem_unlock();
}
Пример #27
0
int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, float ppm, char *control_pipe) {
    // Catch all signals possible - it is vital we kill the DMA engine
    // on process exit!
    for (int i = 0; i < 64; i++) {
        struct sigaction sa;

        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = terminate;
        sigaction(i, &sa, NULL);
    }
        
    dma_reg = map_peripheral(DMA_VIRT_BASE, DMA_LEN);
    pwm_reg = map_peripheral(PWM_VIRT_BASE, PWM_LEN);
    clk_reg = map_peripheral(CLK_VIRT_BASE, CLK_LEN);
    gpio_reg = map_peripheral(GPIO_VIRT_BASE, GPIO_LEN);

    // Use the mailbox interface to the VC to ask for physical memory.
    mbox.handle = mbox_open();
    if (mbox.handle < 0)
        fatal("Failed to open mailbox. Check kernel support for vcio / BCM2708 mailbox.\n");
    printf("Allocating physical memory: size = %d     ", NUM_PAGES * 4096);
    if(! (mbox.mem_ref = mem_alloc(mbox.handle, NUM_PAGES * 4096, 4096, MEM_FLAG))) {
        fatal("Could not allocate memory.\n");
    }
    // TODO: How do we know that succeeded?
    printf("mem_ref = %u     ", mbox.mem_ref);
    if(! (mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref))) {
        fatal("Could not lock memory.\n");
    }
    printf("bus_addr = %x     ", mbox.bus_addr);
    if(! (mbox.virt_addr = mapmem(BUS_TO_PHYS(mbox.bus_addr), NUM_PAGES * 4096))) {
        fatal("Could not map memory.\n");
    }
    printf("virt_addr = %p\n", mbox.virt_addr);
    

    // GPIO4 needs to be ALT FUNC 0 to output the clock
    gpio_reg[GPFSEL0] = (gpio_reg[GPFSEL0] & ~(7 << 12)) | (4 << 12);

    // Program GPCLK to use MASH setting 1, so fractional dividers work
    clk_reg[GPCLK_CNTL] = 0x5A << 24 | 6;
    udelay(100);
    clk_reg[GPCLK_CNTL] = 0x5A << 24 | 1 << 9 | 1 << 4 | 6;

    ctl = (struct control_data_s *) mbox.virt_addr;
    dma_cb_t *cbp = ctl->cb;
    uint32_t phys_sample_dst = CM_GP0DIV;
    uint32_t phys_pwm_fifo_addr = PWM_PHYS_BASE + 0x18;


    // Calculate the frequency control word
    // The fractional part is stored in the lower 12 bits
    uint32_t freq_ctl = ((float)(PLLFREQ / carrier_freq)) * ( 1 << 12 );


    for (int i = 0; i < NUM_SAMPLES; i++) {
        ctl->sample[i] = 0x5a << 24 | freq_ctl;    // Silence
        // Write a frequency sample
        cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP;
        cbp->src = mem_virt_to_phys(ctl->sample + i);
        cbp->dst = phys_sample_dst;
        cbp->length = 4;
        cbp->stride = 0;
        cbp->next = mem_virt_to_phys(cbp + 1);
        cbp++;
        // Delay
        cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP | BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(5);
        cbp->src = mem_virt_to_phys(mbox.virt_addr);
        cbp->dst = phys_pwm_fifo_addr;
        cbp->length = 4;
        cbp->stride = 0;
        cbp->next = mem_virt_to_phys(cbp + 1);
        cbp++;
    }
    cbp--;
    cbp->next = mem_virt_to_phys(mbox.virt_addr);

    // Here we define the rate at which we want to update the GPCLK control 
    // register.
    //
    // Set the range to 2 bits. PLLD is at 500 MHz, therefore to get 228 kHz
    // we need a divisor of 500000 / 2 / 228 = 1096.491228
    //
    // This is 1096 + 2012*2^-12 theoretically
    //
    // However the fractional part may have to be adjusted to take the actual
    // frequency of your Pi's oscillator into account. For example on my Pi,
    // the fractional part should be 1916 instead of 2012 to get exactly 
    // 228 kHz. However RDS decoding is still okay even at 2012.
    //
    // So we use the 'ppm' parameter to compensate for the oscillator error

    float divider = (500000./(2*228*(1.+ppm/1.e6)));
    uint32_t idivider = (uint32_t) divider;
    uint32_t fdivider = (uint32_t) ((divider - idivider)*pow(2, 12));
    
    printf("ppm corr is %.4f, divider is %.4f (%d + %d*2^-12) [nominal 1096.4912].\n", 
                ppm, divider, idivider, fdivider);

    pwm_reg[PWM_CTL] = 0;
    udelay(10);
    clk_reg[PWMCLK_CNTL] = 0x5A000006;              // Source=PLLD and disable
    udelay(100);
    // theorically : 1096 + 2012*2^-12
    clk_reg[PWMCLK_DIV] = 0x5A000000 | (idivider<<12) | fdivider;
    udelay(100);
    clk_reg[PWMCLK_CNTL] = 0x5A000216;              // Source=PLLD and enable + MASH filter 1
    udelay(100);
    pwm_reg[PWM_RNG1] = 2;
    udelay(10);
    pwm_reg[PWM_DMAC] = PWMDMAC_ENAB | PWMDMAC_THRSHLD;
    udelay(10);
    pwm_reg[PWM_CTL] = PWMCTL_CLRF;
    udelay(10);
    pwm_reg[PWM_CTL] = PWMCTL_USEF1 | PWMCTL_PWEN1;
    udelay(10);
    

    // Initialise the DMA
    dma_reg[DMA_CS] = BCM2708_DMA_RESET;
    udelay(10);
    dma_reg[DMA_CS] = BCM2708_DMA_INT | BCM2708_DMA_END;
    dma_reg[DMA_CONBLK_AD] = mem_virt_to_phys(ctl->cb);
    dma_reg[DMA_DEBUG] = 7; // clear debug error flags
    dma_reg[DMA_CS] = 0x10880001;    // go, mid priority, wait for outstanding writes

    
    uint32_t last_cb = (uint32_t)ctl->cb;

    // Data structures for baseband data
    float data[DATA_SIZE];
    int data_len = 0;
    int data_index = 0;

    // Initialize the baseband generator
    if(fm_mpx_open(audio_file, DATA_SIZE) < 0) return 1;
    
    // Initialize the RDS modulator
    char myps[9] = {0};
    set_rds_pi(pi);
    set_rds_rt(rt);
    uint16_t count = 0;
    uint16_t count2 = 0;
    int varying_ps = 0;
    
    if(ps) {
        set_rds_ps(ps);
        printf("PI: %04X, PS: \"%s\".\n", pi, ps);
    } else {
        printf("PI: %04X, PS: <Varying>.\n", pi);
        varying_ps = 1;
    }
    printf("RT: \"%s\"\n", rt);
    
    // Initialize the control pipe reader
    if(control_pipe) {
        if(open_control_pipe(control_pipe) == 0) {
            printf("Reading control commands on %s.\n", control_pipe);
        } else {
            printf("Failed to open control pipe: %s.\n", control_pipe);
            control_pipe = NULL;
        }
    }
    
    
    printf("Starting to transmit on %3.1f MHz.\n", carrier_freq/1e6);

    for (;;) {
        // Default (varying) PS
        if(varying_ps) {
            if(count == 512) {
                snprintf(myps, 9, "%08d", count2);
                set_rds_ps(myps);
                count2++;
            }
            if(count == 1024) {
                set_rds_ps("RPi-Live");
                count = 0;
            }
            count++;
        }
        
        if(control_pipe && poll_control_pipe() == CONTROL_PIPE_PS_SET) {
            varying_ps = 0;
        }
        
        usleep(5000);

        uint32_t cur_cb = mem_phys_to_virt(dma_reg[DMA_CONBLK_AD]);
        int last_sample = (last_cb - (uint32_t)mbox.virt_addr) / (sizeof(dma_cb_t) * 2);
        int this_sample = (cur_cb - (uint32_t)mbox.virt_addr) / (sizeof(dma_cb_t) * 2);
        int free_slots = this_sample - last_sample;

        if (free_slots < 0)
            free_slots += NUM_SAMPLES;

        while (free_slots >= SUBSIZE) {
            // get more baseband samples if necessary
            if(data_len == 0) {
                if( fm_mpx_get_samples(data) < 0 ) {
                    terminate(0);
                }
                data_len = DATA_SIZE;
                data_index = 0;
            }
            
            float dval = data[data_index] * (DEVIATION / 10.);
            data_index++;
            data_len--;

            int intval = (int)((floor)(dval));
            //int frac = (int)((dval - (float)intval) * SUBSIZE);


            ctl->sample[last_sample++] = (0x5A << 24 | freq_ctl) + intval; //(frac > j ? intval + 1 : intval);
            if (last_sample == NUM_SAMPLES)
                last_sample = 0;

            free_slots -= SUBSIZE;
        }
        last_cb = (uint32_t)mbox.virt_addr + last_sample * sizeof(dma_cb_t) * 2;
    }

    return 0;
}