/* Because the lscsa and code may cross segment boundaires, we check to see if mappings are required for the start and end of each range. We currently assume that the mappings are smaller that one segment - if not, something is seriously wrong.  */
void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, void *code, int code_size)
/* Because the lscsa and code may cross segment boundaires, we check to see if mappings are required for the start and end of each range. We currently assume that the mappings are smaller that one segment - if not, something is seriously wrong.  */
void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, void *code, int code_size)
{
	struct spu_slb slbs[4];
	int i, nr_slbs = 0;
	void *addrs[] = {
		lscsa, (void *)lscsa + sizeof(*lscsa) - 1,
		code, code + code_size - 1
	};
	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
		if (__slb_present(slbs, nr_slbs, addrs[i]))
			continue;
		__spu_kernel_slb(addrs[i], &slbs[nr_slbs]);
		nr_slbs++;
	}
	spin_lock_irq(&spu->register_lock);
	for (i = 0; i < nr_slbs; i++)
		spu_load_slb(spu, i, &slbs[i]);
	spin_unlock_irq(&spu->register_lock);
}