From: Simon Kallweit <simon.kallweit@intefo.ch>
To: eCos Patches List <ecos-patches@ecos.sourceware.org>
Subject: synth flash NOR simulation (with patch)
Date: Tue, 23 Dec 2008 08:32:00 -0000 [thread overview]
Message-ID: <4950A1F8.8070600@intefo.ch> (raw)
[-- Attachment #1: Type: text/plain, Size: 53 bytes --]
Sorry, somehow messed up the patch :) Here we go ...
[-- Attachment #2: synth_flash_nor_simulation.patch --]
[-- Type: text/x-diff, Size: 12008 bytes --]
diff -r 2edda4c0b910 packages/devs/flash/synth/current/ChangeLog
--- a/packages/devs/flash/synth/current/ChangeLog Fri Dec 19 17:33:12 2008 +0100
+++ b/packages/devs/flash/synth/current/ChangeLog Tue Dec 23 09:30:41 2008 +0100
@@ -1,3 +1,9 @@
+2008-12-23 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/flash_erase_block.c:
+ * src/flash_program_buf.c:
+ Implemented simulation of proper NOR flash writes. General cleanup.
+
2008-12-18 Simon Kallweit <simon.kallweit@intefo.ch>
* src/synth.c: Fixed error check of mmap call.
diff -r 2edda4c0b910 packages/devs/flash/synth/current/src/flash_erase_block.c
--- a/packages/devs/flash/synth/current/src/flash_erase_block.c Fri Dec 19 17:33:12 2008 +0100
+++ b/packages/devs/flash/synth/current/src/flash_erase_block.c Tue Dec 23 09:30:41 2008 +0100
@@ -56,17 +56,24 @@
#include <pkgconf/devs_flash_synth.h>
#include <cyg/infra/cyg_ass.h>
#include <cyg/io/flash.h>
+#include <cyg/io/flash_dev.h>
#include <string.h> // memset
-/* This helps speed up the erase. */
-static char empty[4096];
-static cyg_bool empty_inited = false;
+#ifndef MIN
+#define MIN(x,y) ((x)<(y) ? (x) : (y))
+#endif
int flash_erase_block(volatile flash_t *block, unsigned int block_size)
{
- int i;
- int offset = (int)block;
- offset -= (int)cyg_dev_flash_synth_base;
+ unsigned int offset = (unsigned int) block;
+ size_t remaining;
+ int write_size;
+
+ // This helps speed up the erasing
+ static cyg_uint8 empty[4096];
+ static cyg_bool empty_inited;
+
+ offset -= (unsigned int) cyg_dev_flash_synth_base;
cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset,
CYG_HAL_SYS_SEEK_SET);
@@ -75,16 +82,14 @@
memset(empty, 0xff, sizeof(empty));
empty_inited = true;
}
+
+ remaining = flash_info.block_size;
- CYG_ASSERT(sizeof(empty) < block_size,
- "Eckk! Can't work with such small blocks");
- CYG_ASSERT((block_size % sizeof(empty)) == 0,
- "Eckk! Can't work with that odd size block");
+ while (remaining) {
+ write_size = MIN(remaining, sizeof(empty));
+ cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, empty, write_size);
+ remaining -= write_size;
+ }
- for (i=0; (i * sizeof(empty)) < block_size; i++) {
- cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, empty, sizeof(empty));
- }
return FLASH_ERR_OK;
}
-
-
diff -r 2edda4c0b910 packages/devs/flash/synth/current/src/flash_program_buf.c
--- a/packages/devs/flash/synth/current/src/flash_program_buf.c Fri Dec 19 17:33:12 2008 +0100
+++ b/packages/devs/flash/synth/current/src/flash_program_buf.c Tue Dec 23 09:30:41 2008 +0100
@@ -56,16 +56,39 @@
#include <cyg/hal/hal_io.h>
#include <cyg/io/flash.h>
+#ifndef MIN
+#define MIN(x,y) ((x)<(y) ? (x) : (y))
+#endif
+
int
flash_program_buf(volatile flash_t *addr, flash_t *data, int len,
unsigned long block_mask, int buffer_size)
{
-
- int offset = (int)addr;
- offset -= (int)cyg_dev_flash_synth_base;
+ unsigned int offset = (unsigned int) addr;
+ cyg_uint8 *buf = (cyg_uint8 *) data;
- cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset, CYG_HAL_SYS_SEEK_SET);
- cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, data, len);
-
+ // This helps speed up the programming
+ static cyg_uint8 tmp[4096];
+
+ offset -= (unsigned int) cyg_dev_flash_synth_base;
+
+ while (len > 0) {
+ int i;
+ int write_size = MIN(len, sizeof(tmp));
+ // Writing to NOR flash only sets bits from 1 to 0, not vice-versa
+ cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset,
+ CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_read(cyg_dev_flash_synth_flashfd, tmp, write_size);
+ for (i = 0; i < write_size; i++)
+ tmp[i] = tmp[i] & buf[i];
+ cyg_hal_sys_lseek(cyg_dev_flash_synth_flashfd, offset,
+ CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_write(cyg_dev_flash_synth_flashfd, tmp, write_size);
+ // Process next chunk
+ buf += write_size;
+ offset += write_size;
+ len -= write_size;
+ }
+
return FLASH_ERR_OK;
}
diff -r 2edda4c0b910 packages/devs/flash/synthv2/current/ChangeLog
--- a/packages/devs/flash/synthv2/current/ChangeLog Fri Dec 19 17:33:12 2008 +0100
+++ b/packages/devs/flash/synthv2/current/ChangeLog Tue Dec 23 09:30:41 2008 +0100
@@ -1,3 +1,8 @@
+2008-12-23 Simon Kallweit <simon.kallweit@intefo.ch>
+
+ * src/synth.c: Implemented simulation of proper NOR flash writes.
+ General cleanup.
+
2008-12-18 Simon Kallweit <simon.kallweit@intefo.ch>
* src/synth.c: Fixed error check of mmap call.
diff -r 2edda4c0b910 packages/devs/flash/synthv2/current/src/synth.c
--- a/packages/devs/flash/synthv2/current/src/synth.c Fri Dec 19 17:33:12 2008 +0100
+++ b/packages/devs/flash/synthv2/current/src/synth.c Tue Dec 23 09:30:41 2008 +0100
@@ -67,15 +67,16 @@
static int
synth_flash_init(struct cyg_flash_dev *dev)
{
- struct cyg_flash_synth_priv *priv = (struct cyg_flash_synth_priv*)dev->priv;
+ struct cyg_flash_synth_priv *priv =
+ (struct cyg_flash_synth_priv *) dev->priv;
cyg_flashaddr_t base;
- int flags=CYG_HAL_SYS_MAP_SHARED;
+ int flags = CYG_HAL_SYS_MAP_SHARED;
- priv->flashfd =
- cyg_hal_sys_open(priv->filename,
- CYG_HAL_SYS_O_RDWR,
- CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|
- CYG_HAL_SYS_S_IRWXO);
+ priv->flashfd = cyg_hal_sys_open(
+ priv->filename,
+ CYG_HAL_SYS_O_RDWR,
+ CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
+
if (priv->flashfd == -ENOENT) {
long w, bytesleft;
char buf[128];
@@ -84,46 +85,43 @@
priv->filename,
CYG_HAL_SYS_O_RDWR|CYG_HAL_SYS_O_CREAT,
CYG_HAL_SYS_S_IRWXU|CYG_HAL_SYS_S_IRWXG|CYG_HAL_SYS_S_IRWXO);
- CYG_ASSERT( priv->flashfd >= 0,
- "Opening of the file for the synth flash failed!");
- // fill with 0xff
- memset( buf, 0xff, sizeof(buf) );
+ CYG_ASSERT(priv->flashfd >= 0,
+ "Opening of the file for the synth flash failed!");
+
+ // Fill with 0xff
+ memset(buf, 0xff, sizeof(buf));
bytesleft = priv->block_size * priv->blocks +
priv->boot_block_size * priv->boot_blocks;
-
while (bytesleft > 0) {
int bytesneeded;
- bytesneeded = bytesleft < sizeof(buf) ?
- bytesleft : sizeof(buf);
-
- w = cyg_hal_sys_write( priv->flashfd, buf,
- bytesneeded );
- CYG_ASSERT(w == bytesneeded,
- "initialization of flash file failed");
+ bytesneeded = bytesleft < sizeof(buf) ? bytesleft : sizeof(buf);
+ w = cyg_hal_sys_write(priv->flashfd, buf, bytesneeded);
+ CYG_ASSERT(w == bytesneeded, "initialization of flash file failed");
bytesleft -= bytesneeded;
- } // while
+ }
}
- CYG_ASSERT( priv->flashfd >= 0,
- "Opening of the file for the synth flash failed!");
- if ( priv->flashfd <= 0 ) {
+
+ CYG_ASSERT(priv->flashfd >= 0,
+ "Opening of the file for the synth flash failed!");
+
+ if (priv->flashfd <= 0)
return CYG_FLASH_ERR_HWR;
- }
- if (dev->start != 0) {
+ if (dev->start != 0)
flags |= CYG_HAL_SYS_MAP_FIXED;
- }
- base = (cyg_flashaddr_t)cyg_hal_sys_mmap(
- (void *)dev->start,
+
+ base = (cyg_flashaddr_t) cyg_hal_sys_mmap(
+ (void *) dev->start,
priv->blocks * priv->block_size +
priv->boot_block_size * priv->boot_blocks,
CYG_HAL_SYS_PROT_READ,
flags,
priv->flashfd,
0l);
- CYG_ASSERT( base != -1, "mmap of flash file failed!" );
- if (base == -1) {
+ CYG_ASSERT(base != -1, "mmap of flash file failed!");
+ if (base == -1)
return CYG_FLASH_ERR_HWR;
- }
+
dev->start = base;
dev->end = base + (priv->blocks * priv->block_size) +
(priv->boot_blocks * priv->boot_block_size) - 1;
@@ -150,30 +148,26 @@
return CYG_FLASH_ERR_OK;
}
-/* This helps speed up the erase. */
-static char empty[4096];
-static cyg_bool empty_inited = false;
-
// Return the size of the block which is at the given address.
// __inline__ so that we know it will be in RAM, not ROM.
static __inline__ size_t
flash_block_size(struct cyg_flash_dev *dev, const cyg_flashaddr_t addr)
{
- int i;
- size_t offset;
+ int i;
+ cyg_flashaddr_t offset;
+ CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device");
- CYG_ASSERT((addr >= dev->start) && (addr <= dev->end), "Not inside device");
-
- offset = addr - dev->start;
- for (i=0; i < dev->num_block_infos; i++) {
- if (offset < (dev->block_info[i].blocks * dev->block_info[i].block_size))
- return dev->block_info[i].block_size;
- offset = offset -
- (dev->block_info[i].blocks * dev->block_info[i].block_size);
- }
- CYG_FAIL("Programming error");
- return 0;
+ offset = addr - dev->start;
+ for (i=0; i < dev->num_block_infos; i++) {
+ if (offset < (dev->block_info[i].blocks *
+ dev->block_info[i].block_size))
+ return dev->block_info[i].block_size;
+ offset = offset -
+ (dev->block_info[i].blocks * dev->block_info[i].block_size);
+ }
+ CYG_FAIL("Programming error");
+ return 0;
}
static int
@@ -181,14 +175,17 @@
cyg_flashaddr_t block_base)
{
const struct cyg_flash_synth_priv *priv = dev->priv;
- int offset = (int)block_base;
+ cyg_flashaddr_t offset = block_base;
size_t remaining;
int write_size;
+
+ // This helps speed up the erasing
+ static cyg_uint8 empty[4096];
+ static cyg_bool empty_inited;
offset -= dev->start;
- cyg_hal_sys_lseek(priv->flashfd, offset,
- CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
if (!empty_inited) {
memset(empty, 0xff, sizeof(empty));
@@ -202,6 +199,7 @@
cyg_hal_sys_write(priv->flashfd, empty, write_size);
remaining -= write_size;
}
+
return CYG_FLASH_ERR_OK;
}
@@ -211,22 +209,39 @@
const void* data, size_t len)
{
const struct cyg_flash_synth_priv *priv = dev->priv;
- int offset = base;
+ cyg_flashaddr_t offset = base;
+ cyg_uint8 *buf = (cyg_uint8 *) data;
+
+ // This helps speed up the programming
+ static cyg_uint8 tmp[4096];
+
offset -= dev->start;
- cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
- cyg_hal_sys_write(priv->flashfd, data, len);
-
+ while (len > 0) {
+ int i;
+ int write_size = MIN(len, sizeof(tmp));
+ // Writing to NOR flash only sets bits from 1 to 0, not vice-versa
+ cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_read(priv->flashfd, tmp, write_size);
+ for (i = 0; i < write_size; i++)
+ tmp[i] = tmp[i] & buf[i];
+ cyg_hal_sys_lseek(priv->flashfd, offset, CYG_HAL_SYS_SEEK_SET);
+ cyg_hal_sys_write(priv->flashfd, tmp, write_size);
+ // Process next chunk
+ buf += write_size;
+ offset += write_size;
+ len -= write_size;
+ }
+
return CYG_FLASH_ERR_OK;
}
#define QUERY "Linux Synthetic Flash"
static size_t
-synth_flash_query(struct cyg_flash_dev *dev, void * data,
- size_t len)
+synth_flash_query(struct cyg_flash_dev *dev, void * data, size_t len)
{
- memcpy(data,QUERY,sizeof(QUERY));
+ memcpy(data, QUERY, sizeof(QUERY));
return sizeof(QUERY);
}
next reply other threads:[~2008-12-23 8:32 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-23 8:32 Simon Kallweit [this message]
2008-12-23 18:29 ` Andrew Lunn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4950A1F8.8070600@intefo.ch \
--to=simon.kallweit@intefo.ch \
--cc=ecos-patches@ecos.sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).