Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/bhnd/cores/chipc/chipc_slicer.c
Context not available. | |||||
{ | { | ||||
struct chipc_spi_softc *sc; | struct chipc_spi_softc *sc; | ||||
device_t chipc, spi, spibus; | device_t chipc, spi, spibus; | ||||
char *err_msg = "OK"; | |||||
BHND_DEBUG_DEV(dev, "initting SPI slicer: %s", device_get_name(dev)); | BHND_DEBUG_DEV(dev, "initting SPI slicer: %s", device_get_name(dev)); | ||||
/* must be SPI-attached flash */ | /* must be SPI-attached flash */ | ||||
spibus = device_get_parent(dev); | spibus = device_get_parent(dev); | ||||
if (spibus == NULL) { | if (spibus == NULL) { | ||||
BHND_ERROR_DEV(dev, "no found ChipCommon SPI BUS device"); | err_msg = "no found ChipCommon SPI BUS device"; | ||||
return (ENXIO); | goto error; | ||||
} | } | ||||
spi = device_get_parent(spibus); | spi = device_get_parent(spibus); | ||||
if (spi == NULL) { | if (spi == NULL) { | ||||
BHND_ERROR_DEV(dev, "no found ChipCommon SPI device"); | err_msg = "no found ChipCommon SPI device"; | ||||
return (ENXIO); | goto error; | ||||
} | } | ||||
chipc = device_get_parent(spi); | chipc = device_get_parent(spi); | ||||
if (device_get_devclass(chipc) != devclass_find("bhnd_chipc")) { | if (device_get_devclass(chipc) != devclass_find("bhnd_chipc")) { | ||||
BHND_ERROR_DEV(dev, "no found ChipCommon device"); | err_msg = "no found ChipCommon device"; | ||||
return (ENXIO); | goto error; | ||||
} | } | ||||
sc = device_get_softc(spi); | sc = device_get_softc(spi); | ||||
return (chipc_slicer_walk(dev, sc->sc_flash_res, slices, nslices)); | return (chipc_slicer_walk(dev, sc->sc_flash_res, slices, nslices)); | ||||
error: | |||||
BHND_ERROR_DEV(dev, "%s", err_msg); | |||||
return (ENXIO); | |||||
} | } | ||||
static int | static int | ||||
Context not available. | |||||
chipc_slicer_walk(device_t dev, struct resource *res, | chipc_slicer_walk(device_t dev, struct resource *res, | ||||
struct flash_slice *slices, int *nslices) | struct flash_slice *slices, int *nslices) | ||||
{ | { | ||||
struct chipc_slicer_info result; | struct chipc_slicer_info result; | ||||
uint32_t fs_ofs; | struct flash_slice *tmp; | ||||
uint32_t fw_len; | uint32_t fs_ofs; | ||||
int err; | uint32_t fw_len; | ||||
int err, cnt; | |||||
*nslices = 0; | *nslices = 0; | ||||
tmp = slices; | |||||
err = chipc_slicer_scan(dev, res, fw_magics, aux_magics, &result); | err = chipc_slicer_scan(dev, res, fw_magics, aux_magics, &result); | ||||
if (err != 0) { | if (err != 0) { | ||||
Context not available. | |||||
* GEOM IO will panic if offset is not aligned | * GEOM IO will panic if offset is not aligned | ||||
* on sector size, i.e. 512 bytes | * on sector size, i.e. 512 bytes | ||||
*/ | */ | ||||
if (fs_ofs % 0x200 != 0) { | if ((fs_ofs & 0x1FF) != 0) { | ||||
BHND_WARN_DEV(dev, "WARNING! filesystem offset should be" | BHND_WARN_DEV(dev, "WARNING! filesystem offset should be" | ||||
" aligned on sector size (%d bytes)", 0x200); | " aligned on sector size (%d bytes)\n" | ||||
BHND_WARN_DEV(dev, "ignoring TRX firmware image"); | " ignoring TRX firmware image", 0x200); | ||||
break; | break; | ||||
} | } | ||||
slices[*nslices].base = result.fw_offset + fs_ofs; | tmp->base = result.fw_offset + fs_ofs; | ||||
slices[*nslices].size = fw_len - fs_ofs; | tmp->size = fw_len - fs_ofs; | ||||
slices[*nslices].label = "rootfs"; | tmp->label = "rootfs"; | ||||
*nslices += 1; | cnt++; | ||||
tmp++; | |||||
if (fw_len + CHIPC_SLICER_CFGSIZE <= result.fw_size) { | |||||
/* configuration slice */ | if (fw_len + CHIPC_SLICER_CFGSIZE > result.fw_size) | ||||
slices[*nslices].size = CHIPC_SLICER_CFGSIZE; | { | ||||
slices[*nslices].base = result.fw_end - | /* no cfg slice, break */ | ||||
slices[*nslices].size; | break; | ||||
slices[*nslices].base = (slices[*nslices].base / 0x10000) * 0x10000; | |||||
slices[*nslices].label = "cfg"; | |||||
*nslices += 1; | |||||
} | } | ||||
/* configuration slice */ | |||||
tmp->size = CHIPC_SLICER_CFGSIZE; | |||||
tmp->base = ((result.fw_end - CHIPC_SLICER_CFGSIZE) & | |||||
~CHIPC_SLICER_CFGSIZE); | |||||
tmp->label = "cfg"; | |||||
cnt++; | |||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
BHND_TRACE("slicer: done"); | BHND_TRACE("slicer: found %d partitions", cnt); | ||||
*nslices = cnt; | |||||
return (0); | return (0); | ||||
} | } | ||||
Context not available. |