axisflashmap.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:11k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Physical mapping layer for MTD using the Axis partitiontable format
  3.  *
  4.  * Copyright (c) 2001, 2002 Axis Communications AB
  5.  *
  6.  * This file is under the GPL.
  7.  *
  8.  * First partition is always sector 0 regardless of if we find a partitiontable
  9.  * or not. In the start of the next sector, there can be a partitiontable that
  10.  * tells us what other partitions to define. If there isn't, we use a default
  11.  * partition split defined below.
  12.  *
  13.  * $Log: axisflashmap.c,v $
  14.  * Revision 1.23  2002/05/13 12:12:28  johana
  15.  * Allow compile without CONFIG_MTD_MTDRAM but warn at compiletime and
  16.  * be informative at runtime.
  17.  *
  18.  * Revision 1.22  2002/05/13 10:24:44  johana
  19.  * Added #if checks on MTDRAM CONFIG
  20.  *
  21.  * Revision 1.21  2002/05/06 16:05:20  johana
  22.  * Removed debug printout.
  23.  *
  24.  * Revision 1.20  2002/05/06 16:03:00  johana
  25.  * No more cramfs as root hack in generic code.
  26.  * It's handled by axisflashmap using mtdram.
  27.  *
  28.  * Revision 1.19  2002/03/15 17:10:28  bjornw
  29.  * Changed comment about cached access since we changed this before
  30.  *
  31.  * Revision 1.18  2002/03/05 17:06:15  jonashg
  32.  * Try amd_flash probe before cfi_probe since amd_flash driver can handle two
  33.  * (or more) flash chips of different model and the cfi driver cannot.
  34.  *
  35.  * Revision 1.17  2001/11/12 19:42:38  pkj
  36.  * Fixed compiler warnings.
  37.  *
  38.  * Revision 1.16  2001/11/08 11:18:58  jonashg
  39.  * Always read from uncached address to avoid problems with flushing
  40.  * cachelines after write and MTD-erase. No performance loss have been
  41.  * seen yet.
  42.  *
  43.  * Revision 1.15  2001/10/19 12:41:04  jonashg
  44.  * Name of probe has changed in MTD.
  45.  *
  46.  * Revision 1.14  2001/09/21 07:14:10  jonashg
  47.  * Made root filesystem (cramfs) use mtdblock driver when booting from flash.
  48.  *
  49.  * Revision 1.13  2001/08/15 13:57:35  jonashg
  50.  * Entire MTD updated to the linux 2.4.7 version.
  51.  *
  52.  * Revision 1.12  2001/06/11 09:50:30  jonashg
  53.  * Oops, 2MB is 0x200000 bytes.
  54.  *
  55.  * Revision 1.11  2001/06/08 11:39:44  jonashg
  56.  * Changed sizes and offsets in axis_default_partitions to use
  57.  * CONFIG_ETRAX_PTABLE_SECTOR.
  58.  *
  59.  * Revision 1.10  2001/05/29 09:42:03  jonashg
  60.  * Use macro for end marker length instead of sizeof.
  61.  *
  62.  * Revision 1.9  2001/05/29 08:52:52  jonashg
  63.  * Gave names to the magic fours (size of the ptable end marker).
  64.  *
  65.  * Revision 1.8  2001/05/28 15:36:20  jonashg
  66.  * * Removed old comment about ptable location in flash (it's a CONFIG_ option).
  67.  * * Variable ptable was initialized twice to the same value.
  68.  *
  69.  * Revision 1.7  2001/04/05 13:41:46  markusl
  70.  * Updated according to review remarks
  71.  *
  72.  * Revision 1.6  2001/03/07 09:21:21  bjornw
  73.  * No need to waste .data
  74.  *
  75.  * Revision 1.5  2001/03/06 16:27:01  jonashg
  76.  * Probe the entire flash area for flash devices.
  77.  *
  78.  * Revision 1.4  2001/02/23 12:47:15  bjornw
  79.  * Uncached flash in LOW_MAP moved from 0xe to 0x8
  80.  *
  81.  * Revision 1.3  2001/02/16 12:11:45  jonashg
  82.  * MTD driver amd_flash is now included in MTD CVS repository.
  83.  * (It's now in drivers/mtd).
  84.  *
  85.  * Revision 1.2  2001/02/09 11:12:22  jonashg
  86.  * Support for AMD compatible non-CFI flash chips.
  87.  * Only tested with Toshiba TC58FVT160 so far.
  88.  *
  89.  * Revision 1.1  2001/01/12 17:01:18  bjornw
  90.  * * Added axisflashmap.c, a physical mapping for MTD that reads and understands
  91.  *   Axis partition-table format.
  92.  *
  93.  *
  94.  */
  95. #include <linux/module.h>
  96. #include <linux/types.h>
  97. #include <linux/kernel.h>
  98. #include <linux/config.h>
  99. #include <linux/mtd/mtd.h>
  100. #include <linux/mtd/map.h>
  101. #include <linux/mtd/partitions.h>
  102. #include <linux/mtd/mtdram.h>
  103. #include <asm/axisflashmap.h>
  104. #include <asm/mmu.h>
  105. #ifdef CONFIG_CRIS_LOW_MAP
  106. #define FLASH_UNCACHED_ADDR  KSEG_8
  107. #define FLASH_CACHED_ADDR    KSEG_5
  108. #else
  109. #define FLASH_UNCACHED_ADDR  KSEG_E
  110. #define FLASH_CACHED_ADDR    KSEG_F
  111. #endif
  112. /*
  113.  * WINDOW_SIZE is the total size where the flash chips may be mapped.
  114.  * MTD probes should find all devices there and it does not matter
  115.  * if there are unmapped gaps or aliases (mirrors of flash devices).
  116.  * The MTD probes will ignore them.
  117.  */
  118. #define WINDOW_SIZE  (128 * 1024 * 1024)
  119. extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* From head.S */
  120. /* 
  121.  * Map driver
  122.  *
  123.  * We run into tricky coherence situations if we mix cached with uncached
  124.  * accesses to we use the uncached version here.
  125.  */
  126. static __u8 flash_read8(struct map_info *map, unsigned long ofs)
  127. {
  128. return *(__u8 *)(FLASH_UNCACHED_ADDR + ofs);
  129. }
  130. static __u16 flash_read16(struct map_info *map, unsigned long ofs)
  131. {
  132. return *(__u16 *)(FLASH_UNCACHED_ADDR + ofs);
  133. }
  134. static __u32 flash_read32(struct map_info *map, unsigned long ofs)
  135. {
  136. return *(volatile unsigned int *)(FLASH_UNCACHED_ADDR + ofs);
  137. }
  138. static void flash_copy_from(struct map_info *map, void *to,
  139.     unsigned long from, ssize_t len)
  140. {
  141. memcpy(to, (void *)(FLASH_UNCACHED_ADDR + from), len);
  142. }
  143. static void flash_write8(struct map_info *map, __u8 d, unsigned long adr)
  144. {
  145. *(__u8 *)(FLASH_UNCACHED_ADDR + adr) = d;
  146. }
  147. static void flash_write16(struct map_info *map, __u16 d, unsigned long adr)
  148. {
  149. *(__u16 *)(FLASH_UNCACHED_ADDR + adr) = d;
  150. }
  151. static void flash_write32(struct map_info *map, __u32 d, unsigned long adr)
  152. {
  153. *(__u32 *)(FLASH_UNCACHED_ADDR + adr) = d;
  154. }
  155. static struct map_info axis_map = {
  156. name: "Axis flash",
  157. size: WINDOW_SIZE,
  158. buswidth: CONFIG_ETRAX_FLASH_BUSWIDTH,
  159. read8: flash_read8,
  160. read16: flash_read16,
  161. read32: flash_read32,
  162. copy_from: flash_copy_from,
  163. write8: flash_write8,
  164. write16: flash_write16,
  165. write32: flash_write32,
  166. };
  167. /* If no partition-table was found, we use this default-set.
  168.  */
  169. #define MAX_PARTITIONS         7  
  170. #define NUM_DEFAULT_PARTITIONS 3
  171. /* Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
  172.  * size of one flash block and "filesystem"-partition needs 5 blocks to be able
  173.  * to use JFFS.
  174.  */
  175. static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
  176. {
  177. name: "boot firmware",
  178. size: CONFIG_ETRAX_PTABLE_SECTOR,
  179. offset: 0
  180. },
  181. {
  182. name: "kernel",
  183. size: 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
  184. offset: CONFIG_ETRAX_PTABLE_SECTOR
  185. },
  186. {
  187. name: "filesystem",
  188. size: 5 * CONFIG_ETRAX_PTABLE_SECTOR,
  189. offset: 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
  190. }
  191. };
  192. static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
  193. {
  194. name: "part0",
  195. size: 0,
  196. offset: 0
  197. },
  198. {
  199. name: "part1",
  200. size: 0,
  201. offset: 0
  202. },
  203. {
  204. name: "part2",
  205. size: 0,
  206. offset: 0
  207. },
  208. {
  209. name: "part3",
  210. size: 0,
  211. offset: 0
  212. },
  213. {
  214. name: "part4",
  215. size: 0,
  216. offset: 0
  217. },
  218. {
  219. name: "part5",
  220. size: 0,
  221. offset: 0
  222. },
  223. {
  224. name: "part6",
  225. size: 0,
  226. offset: 0
  227. },
  228. };
  229. /* 
  230.  * This is the master MTD device for which all the others are just
  231.  * auto-relocating aliases.
  232.  */
  233. static struct mtd_info *mymtd;
  234. /* CFI-scan the flash, and if there was a chip, read the partition-table
  235.  * and register the partitions with MTD.
  236.  */
  237. static int __init
  238. init_axis_flash(void)
  239. {
  240. int err = 0;
  241. int pidx = 0;
  242. struct partitiontable_head *ptable_head;
  243. struct partitiontable_entry *ptable;
  244. int use_default_ptable = 1; /* Until proven otherwise */
  245. const char *pmsg = "  /dev/flash%d at 0x%x, size 0x%xn";
  246. printk(KERN_NOTICE "Axis flash mapping: %x at %lxn",
  247.        WINDOW_SIZE, FLASH_CACHED_ADDR);
  248. #ifdef CONFIG_MTD_AMDSTD
  249. mymtd = (struct mtd_info *)do_map_probe("amd_flash", &axis_map);
  250. #endif
  251. #ifdef CONFIG_MTD_CFI
  252. if (!mymtd) {
  253. mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &axis_map);
  254. }
  255. #endif
  256. if(!mymtd) {
  257. printk("%s: No flash chip found!n", axis_map.name);
  258. return -ENXIO;
  259. }
  260. mymtd->module = THIS_MODULE;
  261. ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
  262. CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
  263. pidx++;  /* first partition is always set to the default */
  264. if ((ptable_head->magic == PARTITION_TABLE_MAGIC)
  265.     && (ptable_head->size <
  266. (MAX_PARTITIONS * sizeof(struct partitiontable_entry) +
  267. PARTITIONTABLE_END_MARKER_SIZE))
  268.     && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) +
  269.   ptable_head->size -
  270.   PARTITIONTABLE_END_MARKER_SIZE)
  271. == PARTITIONTABLE_END_MARKER)) {
  272. /* Looks like a start, sane length and end of a
  273.  * partition table, lets check csum etc.
  274.  */
  275. int ptable_ok = 0;
  276. struct partitiontable_entry *max_addr =
  277. (struct partitiontable_entry *)
  278. ((unsigned long)ptable_head + sizeof(*ptable_head) +
  279.  ptable_head->size);
  280. unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
  281. unsigned char *p;
  282. unsigned long csum = 0;
  283. ptable = (struct partitiontable_entry *)
  284. ((unsigned long)ptable_head + sizeof(*ptable_head));
  285. /* Lets be PARANOID, and check the checksum. */
  286. p = (unsigned char*) ptable;
  287. while (p <= (unsigned char*)max_addr) {
  288. csum += *p++;
  289. csum += *p++;
  290. csum += *p++;
  291. csum += *p++;
  292. }
  293. /* printk("  total csum: 0x%08X 0x%08Xn",
  294.    csum, ptable_head->checksum); */
  295. ptable_ok = (csum == ptable_head->checksum);
  296. /* Read the entries and use/show the info.  */
  297. printk(" Found %s partition table at 0x%08lX-0x%08lX.n",
  298.        (ptable_ok ? "valid" : "invalid"),
  299.        (unsigned long)ptable_head,
  300.        (unsigned long)max_addr);
  301. /* We have found a working bootblock.  Now read the
  302.    partition table.  Scan the table.  It ends when
  303.    there is 0xffffffff, that is, empty flash.  */
  304. while (ptable_ok
  305.        && ptable->offset != 0xffffffff
  306.        && ptable < max_addr
  307.        && pidx < MAX_PARTITIONS) {
  308. axis_partitions[pidx].offset = offset + ptable->offset;
  309. axis_partitions[pidx].size = ptable->size;
  310. printk(pmsg, pidx, axis_partitions[pidx].offset,
  311.        axis_partitions[pidx].size);
  312. pidx++;
  313. ptable++;
  314. }
  315. use_default_ptable = !ptable_ok;
  316. }
  317. if (use_default_ptable) {
  318. printk(" Using default partition tablen");
  319. err = add_mtd_partitions(mymtd, axis_default_partitions,
  320.                          NUM_DEFAULT_PARTITIONS);
  321. } else {
  322. if (romfs_in_flash) {
  323. axis_partitions[pidx].name = "romfs";
  324. axis_partitions[pidx].size = romfs_length;
  325. axis_partitions[pidx].offset = romfs_start -
  326.        FLASH_CACHED_ADDR;
  327. axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
  328. printk(" Adding readonly partition for romfs image:n");
  329. printk(pmsg, pidx, axis_partitions[pidx].offset,
  330.        axis_partitions[pidx].size);
  331. pidx++;
  332. }
  333. err = add_mtd_partitions(mymtd, axis_partitions, pidx);
  334. }
  335. if (!err && !romfs_in_flash) {
  336. #ifdef CONFIG_MTD_MTDRAM
  337. /* Allocate, initialise and forget the mtd ram struct
  338.  * when booting from RAM
  339.  */
  340. struct mtd_info *romfs_mtd = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
  341. printk("MTD RAM device romfs_start: 0x%08lX len %lun",
  342.        romfs_start, romfs_length);
  343. #if (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
  344. #error "You must set CONFIG_MTDRAM_TOTAL_SIZE and CONFIG_MTDRAM_ABS_POS to 0"
  345. #endif
  346. err = mtdram_init_device(romfs_mtd, (void*)romfs_start, 
  347.                          romfs_length, "romfs in RAM");
  348. #else
  349. #warning ######################################
  350. #warning # You must enable CONFIG_MTD_MTDRAM  #
  351. #warning # with TOTAL_SIZE 0 and ABS_POS 0 to # 
  352. #warning # be able to boot with cramfs in RAM #
  353. #warning ######################################
  354. /* Maybe overkill to save these bytes in non debug builds, but let's do it..
  355.  * (No point in printing if we don't have a debug port anyway...)
  356.  */
  357. #ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
  358. printk("## Can't mount romfs in RAM using MTDRAM.n");
  359. printk("## You must enable MTD_MTDRAM with TOTAL_SIZE 0 and ABS_POS 0n");
  360. #endif
  361. #endif /* CONFIG_MTD_MTDRAM */
  362. }
  363. return err;
  364. }
  365. /* This adds the above to the kernels init-call chain */
  366. module_init(init_axis_flash);