/* Allocate a framebuffer and an Area Descriptor that points to it. Both are created in the same memory block. The Area Descriptor is updated to point to the framebuffer memory. Memory is aligned as needed.  */
static struct diu_ad* allocate_fb(unsigned int xres, unsigned int yres, unsigned int depth, char **fb)
/* Allocate a framebuffer and an Area Descriptor that points to it. Both are created in the same memory block. The Area Descriptor is updated to point to the framebuffer memory. Memory is aligned as needed.  */
static struct diu_ad* allocate_fb(unsigned int xres, unsigned int yres, unsigned int depth, char **fb)
{
	unsigned long size = xres * yres * depth;
	struct diu_addr addr;
	struct diu_ad *ad;
	size_t ad_size = roundup(sizeof(struct diu_ad), 32);
	if (allocate_buf(&addr, ad_size + size, 32) < 0)
		return NULL;
	ad = addr.vaddr;
	ad->addr = cpu_to_le32(addr.paddr + ad_size);
	ad->aoi_size = cpu_to_le32((yres << 16) | xres);
	ad->src_size_g_alpha = cpu_to_le32((yres << 12) | xres);
	ad->offset_xyi = 0;
	ad->offset_xyd = 0;
	if (fb)
		*fb = addr.vaddr + ad_size;
	return ad;
}