axisflashmap.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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