qe: add ability to upload QE firmware

Anton Vorontsov avorontsov at ru.mvista.com
Fri Oct 19 04:57:38 EST 2007


On Thu, Oct 18, 2007 at 10:08:25AM -0500, Timur Tabi wrote:
> Define the layout of a binary blob that contains a QE firmware and instructions
> on how to upload it.  Add function qe_upload_microcode() to parse the blob
> and perform the actual upload.  Fully define 'struct rsp' in immap_qe.h to
> include the actual RISC Special Registers.
[...]
> I need to add a few fields to the structure, but I would still appreciate
> comments on the structure and the corresponding code.

It seems I'm too lazy to go deep inside the code, but it's okay... because
I believe it is works fine. ;-)

Thus sorry, only fluffy cosmetic notes.

> Signed-off-by: Timur Tabi <timur at freescale.com>
> ---
[...]
> +	if (firmware->length == (length + sizeof(u32))) {
> +		/* Length is valid, and there's a CRC */
> +		crc = be32_to_cpu(*((__be32 *) ((void *) firmware + length)));

Spaces are not needed after "(__be32 *)" and "(void *)". The whole
construction isn't easy to parse, thus spaces are only distracting.

> +		if (crc != crc32(0, firmware, length)) {
> +			printk(KERN_ERR "QE: firmware CRC is invalid\n");
> +			return -EIO;
> +		}
> +	} else if (firmware->length != length) {
> +		printk(KERN_ERR "QE: invalid length(s) in firware structure\n");
> +		return -EPERM;
> +	}
> +
> +	/* If there's only one microcode, then we assume it's common for all
> +	   RISCs, so we set the CERCR.CIR bit to share the IRAM with all RISCs.
> +	   This should be safe even on SOCs with only one RISC.
> +
> +	   If there are multiple 'microcode' structures, but each one points
> +	   to the same microcode binary (ignoring offsets), then we also assume
> +	   that we want share RAM.
> +	 */

Comment style is unorthodox.

> +	if (firmware->count == 1)
> +	      setbits16(&qe_immr->cp.cercr, cpu_to_be16(0x800));
> +	else {

I'd place braces for the first 'if'. No lines added, more good looking.
The CodingStyle also suggest this.

> +		for (i = 1; i < firmware->count; i++)

I'd place braces here too. No rationale though, just better looking.

> +			if (firmware->microcode[i].code_offset !=
> +			    firmware->microcode[0].code_offset)
> +				break;
> +
> +		if (i == firmware->count)
> +			setbits16(&qe_immr->cp.cercr, cpu_to_be16(0x800));

0x800? Desires proper #define.

> +	}
> +
> +	if (firmware->soc.model)
> +		printk(KERN_INFO "QE: uploading microcode '%s' for %u V%u.%u\n",
> +			firmware->id, be16_to_cpu(firmware->soc.model),
> +			firmware->soc.rev_h, firmware->soc.rev_l);
> +	else
> +		printk(KERN_INFO "QE: uploading microcode '%s'\n",
> +			firmware->id);
> +
> +	for (i = 0; i < firmware->count; i++) {
> +		const struct qe_microcode *ucode = &firmware->microcode[i];
> +
> +		code = (void *) firmware + be32_to_cpu(ucode->code_offset);

space after (void *).

> +		/* Use auto-increment */
> +		out_be32(&qe_immr->iram.iadd, cpu_to_be32(0x80080000 |

magic number.

> +			be32_to_cpu(ucode->iram_offset)));
> +
> +		for (j = 0; j < ucode->count; j++)
> +			out_be32(&qe_immr->iram.idata, be32_to_cpu(code[j]));
> +
> +		/* Program the traps.  We program both RISCs, even on platforms
> +		   that only have one.  This *should* be safe. */
> +		for (j = 0; j < 16; j++)
> +			if (ucode->traps[j]) {
> +				u32 trap = be32_to_cpu(ucode->traps[j]);
> +				out_be32(&qe_immr->rsp[0].tibcr[j], trap);

Empty line needed after variable declaration.

> +				out_be32(&qe_immr->rsp[1].tibcr[j], trap);
> +			}
> +	}
> +
> +	/* Enable the traps for both RISCs.  Again, on a single-RISC system,
> +	   this should be safe. */

Comment.

> +	out_be32(&qe_immr->rsp[0].eccr, cpu_to_be32(0x20800000));
> +	out_be32(&qe_immr->rsp[1].eccr, cpu_to_be32(0x20800000));

magic numbers.

Thanks,

-- 
Anton Vorontsov
email: cbou at mail.ru
backup email: ya-cbou at yandex.ru
irc://irc.freenode.net/bd2



More information about the Linuxppc-dev mailing list