static void crisv32_arbiter_config(int region, int unused_slots)
{
	int slot;
	int client;
	int interval = 0;

	/*
	 * This vector corresponds to the hardware arbiter slots (see
	 * the hardware documentation for semantics). We initialize
	 * each slot with a suitable sentinel value outside the valid
	 * range {0 .. NBR_OF_CLIENTS - 1} and replace them with
	 * client indexes. Then it's fed to the hardware.
	 */
	s8 val[NBR_OF_SLOTS];

	for (slot = 0; slot < NBR_OF_SLOTS; slot++)
		val[slot] = -1;

	for (client = 0; client < NBR_OF_CLIENTS; client++) {
		int pos;
		/* Allocate the requested non-zero number of slots, but
		 * also give clients with zero-requests one slot each
		 * while stocks last. We do the latter here, in client
		 * order. This makes sure zero-request clients are the
		 * first to get to any spare slots, else those slots
		 * could, when bandwidth is allocated close to the limit,
		 * all be allocated to low-index non-zero-request clients
		 * in the default-fill loop below. Another positive but
		 * secondary effect is a somewhat better spread of the
		 * zero-bandwidth clients in the vector, avoiding some of
		 * the latency that could otherwise be caused by the
		 * partitioning of non-zero-bandwidth clients at low
		 * indexes and zero-bandwidth clients at high
		 * indexes. (Note that this spreading can only affect the
		 * unallocated bandwidth.)  All the above only matters for
		 * memory-intensive situations, of course.
		 */
		if (!requested_slots[region][client]) {
			/*
			 * Skip inactive clients. Also skip zero-slot
			 * allocations in this pass when there are no known
			 * free slots.
			 */
			if (!active_clients[region][client]
			    || unused_slots <= 0)
				continue;

			unused_slots--;

			/* Only allocate one slot for this client. */
			interval = NBR_OF_SLOTS;
		} else
			interval =
			    NBR_OF_SLOTS / requested_slots[region][client];

		pos = 0;
		while (pos < NBR_OF_SLOTS) {
			if (val[pos] >= 0)
				pos++;
			else {
				val[pos] = client;
				pos += interval;
			}
		}
	}

	client = 0;
	for (slot = 0; slot < NBR_OF_SLOTS; slot++) {
		/*
		 * Allocate remaining slots in round-robin
		 * client-number order for active clients. For this
		 * pass, we ignore requested bandwidth and previous
		 * allocations.
		 */
		if (val[slot] < 0) {
			int first = client;
			while (!active_clients[region][client]) {
				client = (client + 1) % NBR_OF_CLIENTS;
				if (client == first)
					break;
			}
			val[slot] = client;
			client = (client + 1) % NBR_OF_CLIENTS;
		}
		if (region == EXT_REGION)
			REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot,
					val[slot]);
		else if (region == INT_REGION)
			REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot,
					val[slot]);
	}
}
Esempio n. 2
0
static void crisv32_arbiter_config(int region, int unused_slots)
{
	int slot;
	int client;
	int interval = 0;

	/*
                                                              
                                                            
                                                              
                                                         
                                                  
  */
	s8 val[NBR_OF_SLOTS];

	for (slot = 0; slot < NBR_OF_SLOTS; slot++)
		val[slot] = -1;

	for (client = 0; client < NBR_OF_CLIENTS; client++) {
		int pos;
		/*                                                     
                                                       
                                                        
                                                        
                                                      
                                                           
                                                           
                                                         
                                                        
                                                           
                                                      
                                                      
                                               
                                                           
                                                            
                                            
   */
		if (!requested_slots[region][client]) {
			/*
                                                
                                                      
                 
    */
			if (!active_clients[region][client]
			    || unused_slots <= 0)
				continue;

			unused_slots--;

			/*                                         */
			interval = NBR_OF_SLOTS;
		} else
			interval =
			    NBR_OF_SLOTS / requested_slots[region][client];

		pos = 0;
		while (pos < NBR_OF_SLOTS) {
			if (val[pos] >= 0)
				pos++;
			else {
				val[pos] = client;
				pos += interval;
			}
		}
	}

	client = 0;
	for (slot = 0; slot < NBR_OF_SLOTS; slot++) {
		/*
                                            
                                                     
                                                     
                 
   */
		if (val[slot] < 0) {
			int first = client;
			while (!active_clients[region][client]) {
				client = (client + 1) % NBR_OF_CLIENTS;
				if (client == first)
					break;
			}
			val[slot] = client;
			client = (client + 1) % NBR_OF_CLIENTS;
		}
		if (region == EXT_REGION)
			REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot,
					val[slot]);
		else if (region == INT_REGION)
			REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot,
					val[slot]);
	}
}