From b48c3d09495f9ee019fa6411632cdbae8a3e2112 Mon Sep 17 00:00:00 2001 From: Theo de Raadt Date: Sat, 6 Jan 2007 02:48:43 +0000 Subject: make microcode file byte-order independent so that the file is the same on all architectures, and have the driver cope with this as well tested by ian YOU MUST UPDATE YOUR MICROCODE FILE OR THE DRIVER WILL NOT BE HAPPY --- sys/dev/microcode/yds/build.c | 38 +++++++++++++++++++++++++++++--------- sys/dev/pci/yds.c | 33 +++++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 15 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/microcode/yds/build.c b/sys/dev/microcode/yds/build.c index 55f44c6a40d..1dfd81ffcf0 100644 --- a/sys/dev/microcode/yds/build.c +++ b/sys/dev/microcode/yds/build.c @@ -1,4 +1,4 @@ -/* $OpenBSD: build.c,v 1.3 2005/07/12 19:28:53 deraadt Exp $ */ +/* $OpenBSD: build.c,v 1.4 2007/01/06 02:48:42 deraadt Exp $ */ /* * Copyright (c) 2004 Theo de Raadt @@ -27,6 +27,15 @@ #define FILENAME "yds" +void +hswapn(u_int32_t *p, int wcount) +{ + for (; wcount; wcount -=4) { + *p = htonl(*p); + p++; + } +} + int main(int argc, char *argv[]) { @@ -41,17 +50,28 @@ main(int argc, char *argv[]) yf = (struct yds_firmware *)malloc(len); bzero(yf, len); - yf->dsplen = sizeof(yds_dsp_mcode); - yf->ds1len = sizeof(yds_ds1_ctrl_mcode); - yf->ds1elen = sizeof(yds_ds1e_ctrl_mcode); + yf->dsplen = htonl(sizeof(yds_dsp_mcode)); + yf->ds1len = htonl(sizeof(yds_ds1_ctrl_mcode)); + yf->ds1elen = htonl(sizeof(yds_ds1e_ctrl_mcode)); + + bcopy(yds_dsp_mcode, &yf->data[0], sizeof(yds_dsp_mcode)); + hswapn((u_int32_t *)&yf->data[0], sizeof(yds_dsp_mcode)); + + bcopy(yds_ds1_ctrl_mcode, &yf->data[sizeof(yds_dsp_mcode)], + sizeof(yds_ds1_ctrl_mcode)); + hswapn((u_int32_t *)&yf->data[sizeof(yds_dsp_mcode)], + sizeof(yds_ds1_ctrl_mcode)); - bcopy(yds_dsp_mcode, &yf->data[0], yf->dsplen); - bcopy(yds_ds1_ctrl_mcode, &yf->data[yf->dsplen], yf->ds1len); - bcopy(yds_ds1e_ctrl_mcode, &yf->data[yf->dsplen + yf->ds1len], - yf->ds1elen); + bcopy(yds_ds1e_ctrl_mcode, + &yf->data[sizeof(yds_dsp_mcode) + sizeof(yds_ds1_ctrl_mcode)], + sizeof(yds_ds1e_ctrl_mcode)); + hswapn((u_int32_t *)&yf->data[sizeof(yds_dsp_mcode) + + sizeof(yds_ds1_ctrl_mcode)], + sizeof(yds_ds1e_ctrl_mcode)); printf("creating %s length %d [%d+%d+%d]\n", - FILENAME, len, yf->dsplen, yf->ds1len, yf->ds1elen); + FILENAME, len, sizeof(yds_dsp_mcode), + sizeof(yds_ds1_ctrl_mcode), sizeof(yds_ds1e_ctrl_mcode)); fd = open(FILENAME, O_WRONLY|O_CREAT|O_TRUNC, 0644); if (fd == -1) err(1, FILENAME); diff --git a/sys/dev/pci/yds.c b/sys/dev/pci/yds.c index c42d9177a47..ce7c862c4dd 100644 --- a/sys/dev/pci/yds.c +++ b/sys/dev/pci/yds.c @@ -1,4 +1,4 @@ -/* $OpenBSD: yds.c,v 1.27 2005/08/09 04:10:13 mickey Exp $ */ +/* $OpenBSD: yds.c,v 1.28 2007/01/06 02:48:40 deraadt Exp $ */ /* $NetBSD: yds.c,v 1.5 2001/05/21 23:55:04 minoura Exp $ */ /* @@ -91,6 +91,8 @@ int yds_match(struct device *, void *, void *); void yds_attach(struct device *, struct device *, void *); int yds_intr(void *); +static void nswaph(u_int32_t *p, int wcount); + #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) #define KERNADDR(p) ((void *)((p)->addr)) @@ -334,6 +336,15 @@ yds_get_dstype(id) return -1; } +static void +nswaph(u_int32_t *p, int wcount) +{ + for (; wcount; wcount -=4) { + *p = ntohl(*p); + p++; + } +} + static int yds_download_mcode(sc) struct yds_softc *sc; @@ -352,16 +363,23 @@ yds_download_mcode(sc) yf = (struct yds_firmware *)buf; if (sc->sc_flags & YDS_CAP_MCODE_1) { - p = (u_int32_t *)&yf->data[yf->dsplen]; - size = yf->ds1len; + p = (u_int32_t *)&yf->data[ntohl(yf->dsplen)]; + size = ntohl(yf->ds1len); } else if (sc->sc_flags & YDS_CAP_MCODE_1E) { - p = (u_int32_t *)&yf->data[yf->dsplen + yf->ds1len]; - size = yf->ds1elen; + p = (u_int32_t *)&yf->data[ntohl(yf->dsplen) + ntohl(yf->ds1len)]; + size = ntohl(yf->ds1elen); } else { free(buf, M_DEVBUF); return 1; /* unknown */ } + if (size > buflen) { + printf("%s: old firmware file, update please\n", + sc->sc_dev.dv_xname); + free(buf, M_DEVBUF); + return 1; + } + if (yds_disable_dsp(sc)) { free(buf, M_DEVBUF); return 1; @@ -382,9 +400,12 @@ yds_download_mcode(sc) YWRITE2(sc, YDS_GLOBAL_CONTROL, ctrl & ~0x0007); /* Download DSP microcode. */ - YWRITEREGION4(sc, YDS_DSP_INSTRAM, (u_int32_t *)&yf->data[0], yf->dsplen); + nswaph((u_int32_t *)&yf->data[0], ntohl(yf->dsplen)); + YWRITEREGION4(sc, YDS_DSP_INSTRAM, (u_int32_t *)&yf->data[0], + ntohl(yf->dsplen)); /* Download CONTROL microcode. */ + nswaph((u_int32_t *)p, size); YWRITEREGION4(sc, YDS_CTRL_INSTRAM, p, size); yds_enable_dsp(sc); -- cgit v1.2.3