/* Read len bytes starting at offset into buf. Returns number of bytes read. */ int sflash_read(si_t *sih, chipcregs_t *cc, uint offset, uint len, uchar *buf) { uint8 *from, *to; int cnt, i; osl_t *osh; ASSERT(sih); if (!len) return 0; if ((offset + len) > sflash.size) return -22; if ((len >= 4) && (offset & 3)) cnt = 4 - (offset & 3); else if ((len >= 4) && ((uintptr)buf & 3)) cnt = 4 - ((uintptr)buf & 3); else cnt = len; osh = si_osh(sih); if (sih->ccrev == 12) from = (uint8 *)OSL_UNCACHED((void *)SI_FLASH2 + offset); else from = (uint8 *)OSL_CACHED((void *)SI_FLASH2 + offset); to = (uint8 *)buf; if (cnt < 4) { for (i = 0; i < cnt; i ++) { /* Cannot use R_REG because in bigendian that will * xor the address and we don't want that here. */ *to = *from; from ++; to ++; } return cnt; } while (cnt >= 4) { *(uint32 *)to = *(uint32 *)from; from += 4; to += 4; cnt -= 4; } return (len - cnt); }
/* Read len bytes starting at offset into buf. Returns number of bytes read. */ int sflash_read(si_t *sih, chipcregs_t *cc, uint offset, uint len, uchar *buf) { uint8 *from, *to; int cnt, i; osl_t *osh; ASSERT(sih); if (!len) return 0; if ((offset + len) > sflash.size) return -22; if ((len >= 4) && (offset & 3)) cnt = 4 - (offset & 3); else if ((len >= 4) && ((uintptr)buf & 3)) cnt = 4 - ((uintptr)buf & 3); else cnt = len; osh = si_osh(sih); from = (uint8 *)OSL_UNCACHED(SI_FLASH2 + offset); to = (uint8 *)buf; if (cnt < 4) { for (i = 0; i < cnt; i ++) { *to = R_REG(osh, from); from ++; to ++; } return cnt; } while (cnt >= 4) { *(uint32 *)to = R_REG(osh, (uint32 *)from); from += 4; to += 4; cnt -= 4; } return (len - cnt); }
static struct nvram_header * BCMINITFN(find_nvram)(si_t *sih, bool embonly, bool *isemb) { struct nvram_header *nvh; uint32 off, lim = SI_FLASH2_SZ; uint32 flbase = SI_FLASH2; int bootdev; #ifdef NFLASH_SUPPORT hndnand_t *nfl_info = NULL; #endif #ifdef _CFE_ hndsflash_t *sfl_info = NULL; #endif bootdev = soc_boot_dev((void *)sih); #ifdef NFLASH_SUPPORT if (bootdev == SOC_BOOTDEV_NANDFLASH) { /* Init nand anyway */ nfl_info = hndnand_init(sih); if (nfl_info) flbase = nfl_info->phybase; } else #endif /* NFLASH_SUPPORT */ if (bootdev == SOC_BOOTDEV_SFLASH) { #ifdef _CFE_ /* Init nand anyway */ sfl_info = hndsflash_init(sih); if (sfl_info) { flbase = sfl_info->phybase; lim = sfl_info->size; } #else if (sih->ccrev == 42) flbase = SI_NS_NORFLASH; #endif } if (!embonly) { *isemb = FALSE; #ifdef NFLASH_SUPPORT if (nfl_info) { uint32 blocksize; blocksize = nfl_info->blocksize; off = blocksize; for (; off < nfl_boot_size(nfl_info); off += blocksize) { if (hndnand_checkbadb(nfl_info, off) != 0) continue; nvh = (struct nvram_header *)OSL_UNCACHED(flbase + off); if (nvh->magic != NVRAM_MAGIC) continue; /* Read into the nand_nvram */ if ((nvh = nand_find_nvram(nfl_info, off)) == NULL) continue; if (nvram_calc_crc(nvh) == (uint8)nvh->crc_ver_init) return nvh; } } else #endif /* NFLASH_SUPPORT */ { off = FLASH_MIN; while (off <= lim) { nvh = (struct nvram_header *) OSL_UNCACHED(flbase + off - MAX_NVRAM_SPACE); if (nvh->magic == NVRAM_MAGIC) { if (nvram_calc_crc(nvh) == (uint8) nvh->crc_ver_init) { return (nvh); } } off <<= 1; } } #ifdef BCMDBG printf("find_nvram: nvram not found, trying embedded nvram next\n"); #endif /* BCMDBG */ } /* * Provide feedback to user when nvram corruption detected. * Must be non-BCMDBG for customer release. */ printf("Corrupt NVRAM found, trying embedded NVRAM next.\n"); /* Now check embedded nvram */ *isemb = TRUE; nvh = (struct nvram_header *)OSL_UNCACHED(flbase + (4 * 1024)); if (nvh->magic == NVRAM_MAGIC) return (nvh); nvh = (struct nvram_header *)OSL_UNCACHED(flbase + 1024); if (nvh->magic == NVRAM_MAGIC) return (nvh); #ifdef _CFE_ nvh = (struct nvram_header *)embedded_nvram; if (nvh->magic == NVRAM_MAGIC) return (nvh); #endif printf("find_nvram: no nvram found\n"); return (NULL); }
/* Read the flash ID and set the globals */ int sysFlashInit(char *flash_str) { osl_t *osh; uint32 fltype = PFLASH; uint16 flash_vendid = 0; uint16 flash_devid = 0; int idx; struct sflash *sflash; /* * Check for serial flash. */ sih = si_kattach(SI_OSH); ASSERT(sih); osh = si_osh(sih); cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc); flashutl_base = (void *)OSL_UNCACHED((uintptr)SI_FLASH2); /* Select SFLASH ? */ fltype = R_REG(osh, &cc->capabilities) & CC_CAP_FLASH_MASK; if (fltype == SFLASH_ST || fltype == SFLASH_AT) { if (sih->ccrev == 12) flashutl_base = (void *)OSL_UNCACHED((uintptr)SI_FLASH2); else flashutl_base = (void *)OSL_CACHED((uintptr)SI_FLASH2); sflash = sflash_init(sih, cc); flashutl_cmd = &sflash_cmd_t; flashutl_desc = &sflash_desc; flashutl_desc->size = sflash->size; if (flash_str) sprintf(flash_str, "SFLASH %d kB", sflash->size/1024); return (0); } flashutl_wsz = (R_REG(osh, &cc->flash_config) & CC_CFG_DS) ? sizeof(uint16) : sizeof(uint8); ASSERT(flashutl_wsz == sizeof(uint8) || flashutl_wsz == sizeof(uint16)); /* * Parallel flash support * Some flashes have different unlock addresses, try each it turn */ for (idx = 0; fltype == PFLASH && idx < ARRAYSIZE(flash_cmds); idx ++) { flashutl_cmd = &flash_cmds[idx]; if (flashutl_cmd->type == OLD) continue; if (flashutl_cmd->read_id) { cmd(flashutl_cmd->read_id, CMD_ADDR); /* Delay for turn around time */ OSL_DELAY(1); } #ifdef MIPSEB #ifdef BCMHND74K flash_vendid = flash_readword(FLASH_ADDR(0)^6); flash_devid = flash_readword(FLASH_ADDR(2)^6); #else /* !74K, bcm33xx */ flash_vendid = flash_readword(FLASH_ADDR(2)); flash_devid = flash_readword(FLASH_ADDR(0)); #endif /* BCMHND74K */ #else flash_vendid = flash_readword(FLASH_ADDR(0)); flash_devid = flash_readword(FLASH_ADDR(2)); #endif /* MIPSEB */ /* Funky AMD, uses 3 byte device ID so use first byte (4th addr) to * identify it is a 3-byte ID and use the next two bytes (5th & 6th addr) * to form a word for unique identification of format xxyy, where * xx = 5th addr and yy = 6th addr */ if ((flash_vendid == 1) && ((flash_devid == 0x227e && flashutl_wsz == sizeof(uint16)) || (flash_devid == 0x7e && flashutl_wsz == sizeof(uint8)))) { /* Get real devid */ uint16 flash_devid_5th; #ifdef MIPSEB #ifdef BCMHND74K flash_devid_5th = flash_readword(FLASH_ADDR(0x1c)^6) << 8; flash_devid = (flash_readword(FLASH_ADDR(0x1e)^6) & 0xff) | flash_devid_5th; #else /* !74K, bcm33xx */ flash_devid_5th = flash_readword(FLASH_ADDR(0x1e)) << 8; flash_devid = (flash_readword(FLASH_ADDR(0x1c)) & 0xff) | flash_devid_5th; #endif /* BCMHND74K */ #else flash_devid_5th = flash_readword(FLASH_ADDR(0x1c)) << 8; flash_devid = (flash_readword(FLASH_ADDR(0x1e)) & 0xff) | flash_devid_5th; #endif /* MIPSEB */ } flashutl_desc = flashes; while (flashutl_desc->mfgid != 0 && !(flashutl_desc->mfgid == flash_vendid && flashutl_desc->devid == flash_devid)) { flashutl_desc++; } if (flashutl_desc->mfgid != 0) break; } if (flashutl_desc->mfgid == 0) { flashutl_desc = NULL; flashutl_cmd = NULL; } else { flashutl_cmd = flash_cmds; while (flashutl_cmd->type != 0 && flashutl_cmd->type != flashutl_desc->type) flashutl_cmd++; if (flashutl_cmd->type == 0) flashutl_cmd = NULL; } if (flashutl_cmd != NULL) { flash_reset(); } if (flashutl_desc == NULL) { if (flash_str) sprintf(flash_str, "UNKNOWN 0x%x 0x%x", flash_vendid, flash_devid); DPRINT(("Flash type UNKNOWN\n")); return 1; } if (flash_str) strcpy(flash_str, flashutl_desc->desc); DPRINT(("Flash type \"%s\"\n", flashutl_desc->desc)); return 0; }
/* post receive buffers */ void dma_rxfill(dma_info_t *di) { void *p; uint rxin, rxout; uint ctrl; uint n; uint i; uint32 pa; uint rxbufsize; /* * Determine how many receive buffers we're lacking * from the full complement, allocate, initialize, * and post them, then update the chip rx lastdscr. */ rxin = di->rxin; rxout = di->rxout; rxbufsize = di->rxbufsize; n = di->nrxpost - NRXDACTIVE(rxin, rxout); DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); for (i = 0; i < n; i++) { if ((p = PKTGET(di->drv, rxbufsize, FALSE)) == NULL) { DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); di->hnddma.rxnobuf++; break; } /* PR3263 & PR3387 & PR4642 war: rxh.len=0 means dma writes not complete */ *(uint32*)(OSL_UNCACHED(PKTDATA(di->drv, p))) = 0; pa = (uint32) DMA_MAP(di->dev, PKTDATA(di->drv, p), rxbufsize, DMA_RX, p); ASSERT(ISALIGNED(pa, 4)); /* save the free packet pointer */ #if 0 ASSERT(di->rxp[rxout] == NULL); #endif di->rxp[rxout] = p; /* paranoia */ ASSERT(R_SM(&di->rxd[rxout].addr) == 0); /* prep the descriptor control value */ ctrl = rxbufsize; if (rxout == (di->nrxd - 1)) ctrl |= CTRL_EOT; /* init the rx descriptor */ W_SM(&di->rxd[rxout].ctrl, BUS_SWAP32(ctrl)); W_SM(&di->rxd[rxout].addr, BUS_SWAP32(pa + di->dataoffset)); DMA_TRACE(("%s: dma_rxfill: ctrl %08x dataoffset: %08x\n", di->name, BUS_SWAP32(ctrl), BUS_SWAP32(pa + di->dataoffset))); rxout = NEXTRXD(rxout); } di->rxout = rxout; /* update the chip lastdscr pointer */ W_REG(&di->regs->rcvptr, I2B(rxout)); }