Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
1aaaeabf
Commit
1aaaeabf
authored
Nov 28, 2006
by
David Woodhouse
Browse files
Options
Browse Files
Download
Plain Diff
Merge
git://git.infradead.org/~dwmw2/cafe-2.6
parents
7014568b
cad40654
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
2162 additions
and
1 deletion
+2162
-1
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Kconfig
+7
-0
drivers/mtd/nand/Makefile
drivers/mtd/nand/Makefile
+3
-1
drivers/mtd/nand/cafe.c
drivers/mtd/nand/cafe.c
+771
-0
drivers/mtd/nand/cafe_ecc.c
drivers/mtd/nand/cafe_ecc.c
+1381
-0
No files found.
drivers/mtd/nand/Kconfig
View file @
1aaaeabf
...
...
@@ -220,6 +220,13 @@ config MTD_NAND_SHARPSL
tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
depends on MTD_NAND && ARCH_PXA
config MTD_NAND_CAFE
tristate "NAND support for OLPC CAFÉ chip"
depends on PCI
help
Use NAND flash attached to the CAFÉ chip designed for the $100
laptop.
config MTD_NAND_CS553X
tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
depends on MTD_NAND && X86_32 && (X86_PC || X86_GENERICARCH)
...
...
drivers/mtd/nand/Makefile
View file @
1aaaeabf
...
...
@@ -6,6 +6,7 @@
obj-$(CONFIG_MTD_NAND)
+=
nand.o nand_ecc.o
obj-$(CONFIG_MTD_NAND_IDS)
+=
nand_ids.o
obj-$(CONFIG_MTD_NAND_CAFE)
+=
cafe_nand.o
obj-$(CONFIG_MTD_NAND_SPIA)
+=
spia.o
obj-$(CONFIG_MTD_NAND_AMS_DELTA)
+=
ams-delta.o
obj-$(CONFIG_MTD_NAND_TOTO)
+=
toto.o
...
...
@@ -24,4 +25,5 @@ obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
obj-$(CONFIG_MTD_NAND_NDFC)
+=
ndfc.o
obj-$(CONFIG_MTD_NAND_AT91)
+=
at91_nand.o
nand-objs
=
nand_base.o nand_bbt.o
nand-objs
:=
nand_base.o nand_bbt.o
cafe_nand-objs
:=
cafe.o cafe_ecc.o
drivers/mtd/nand/cafe.c
0 → 100644
View file @
1aaaeabf
/*
* Driver for One Laptop Per Child ‘CAFÉ’ controller, aka Marvell 88ALP01
*
* Copyright © 2006 Red Hat, Inc.
* Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
*/
#define DEBUG
#include <linux/device.h>
#undef DEBUG
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#define CAFE_NAND_CTRL1 0x00
#define CAFE_NAND_CTRL2 0x04
#define CAFE_NAND_CTRL3 0x08
#define CAFE_NAND_STATUS 0x0c
#define CAFE_NAND_IRQ 0x10
#define CAFE_NAND_IRQ_MASK 0x14
#define CAFE_NAND_DATA_LEN 0x18
#define CAFE_NAND_ADDR1 0x1c
#define CAFE_NAND_ADDR2 0x20
#define CAFE_NAND_TIMING1 0x24
#define CAFE_NAND_TIMING2 0x28
#define CAFE_NAND_TIMING3 0x2c
#define CAFE_NAND_NONMEM 0x30
#define CAFE_NAND_ECC_RESULT 0x3C
#define CAFE_NAND_DMA_CTRL 0x40
#define CAFE_NAND_DMA_ADDR0 0x44
#define CAFE_NAND_DMA_ADDR1 0x48
#define CAFE_NAND_ECC_SYN01 0x50
#define CAFE_NAND_ECC_SYN23 0x54
#define CAFE_NAND_ECC_SYN45 0x58
#define CAFE_NAND_ECC_SYN67 0x5c
#define CAFE_NAND_READ_DATA 0x1000
#define CAFE_NAND_WRITE_DATA 0x2000
#define CAFE_GLOBAL_CTRL 0x3004
#define CAFE_GLOBAL_IRQ 0x3008
#define CAFE_GLOBAL_IRQ_MASK 0x300c
#define CAFE_NAND_RESET 0x3034
int
cafe_correct_ecc
(
unsigned
char
*
buf
,
unsigned
short
*
chk_syndrome_list
);
struct
cafe_priv
{
struct
nand_chip
nand
;
struct
pci_dev
*
pdev
;
void
__iomem
*
mmio
;
uint32_t
ctl1
;
uint32_t
ctl2
;
int
datalen
;
int
nr_data
;
int
data_pos
;
int
page_addr
;
dma_addr_t
dmaaddr
;
unsigned
char
*
dmabuf
;
};
static
int
usedma
=
1
;
module_param
(
usedma
,
int
,
0644
);
static
int
skipbbt
=
0
;
module_param
(
skipbbt
,
int
,
0644
);
static
int
debug
=
0
;
module_param
(
debug
,
int
,
0644
);
static
int
regdebug
=
0
;
module_param
(
regdebug
,
int
,
0644
);
static
int
checkecc
=
1
;
module_param
(
checkecc
,
int
,
0644
);
static
int
slowtiming
=
0
;
module_param
(
slowtiming
,
int
,
0644
);
/* Hrm. Why isn't this already conditional on something in the struct device? */
#define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0)
/* Make it easier to switch to PIO if we need to */
#define cafe_readl(cafe, addr) readl((cafe)->mmio + CAFE_##addr)
#define cafe_writel(cafe, datum, addr) writel(datum, (cafe)->mmio + CAFE_##addr)
static
int
cafe_device_ready
(
struct
mtd_info
*
mtd
)
{
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
int
result
=
!!
(
cafe_readl
(
cafe
,
NAND_STATUS
)
|
0x40000000
);
uint32_t
irqs
=
cafe_readl
(
cafe
,
NAND_IRQ
);
cafe_writel
(
cafe
,
irqs
,
NAND_IRQ
);
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"NAND device is%s ready, IRQ %x (%x) (%x,%x)
\n
"
,
result
?
""
:
" not"
,
irqs
,
cafe_readl
(
cafe
,
NAND_IRQ
),
cafe_readl
(
cafe
,
GLOBAL_IRQ
),
cafe_readl
(
cafe
,
GLOBAL_IRQ_MASK
));
return
result
;
}
static
void
cafe_write_buf
(
struct
mtd_info
*
mtd
,
const
uint8_t
*
buf
,
int
len
)
{
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
if
(
usedma
)
memcpy
(
cafe
->
dmabuf
+
cafe
->
datalen
,
buf
,
len
);
else
memcpy_toio
(
cafe
->
mmio
+
CAFE_NAND_WRITE_DATA
+
cafe
->
datalen
,
buf
,
len
);
cafe
->
datalen
+=
len
;
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Copy 0x%x bytes to write buffer. datalen 0x%x
\n
"
,
len
,
cafe
->
datalen
);
}
static
void
cafe_read_buf
(
struct
mtd_info
*
mtd
,
uint8_t
*
buf
,
int
len
)
{
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
if
(
usedma
)
memcpy
(
buf
,
cafe
->
dmabuf
+
cafe
->
datalen
,
len
);
else
memcpy_fromio
(
buf
,
cafe
->
mmio
+
CAFE_NAND_READ_DATA
+
cafe
->
datalen
,
len
);
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Copy 0x%x bytes from position 0x%x in read buffer.
\n
"
,
len
,
cafe
->
datalen
);
cafe
->
datalen
+=
len
;
}
static
uint8_t
cafe_read_byte
(
struct
mtd_info
*
mtd
)
{
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
uint8_t
d
;
cafe_read_buf
(
mtd
,
&
d
,
1
);
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Read %02x
\n
"
,
d
);
return
d
;
}
static
void
cafe_nand_cmdfunc
(
struct
mtd_info
*
mtd
,
unsigned
command
,
int
column
,
int
page_addr
)
{
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
int
adrbytes
=
0
;
uint32_t
ctl1
;
uint32_t
doneint
=
0x80000000
;
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"cmdfunc %02x, 0x%x, 0x%x
\n
"
,
command
,
column
,
page_addr
);
if
(
command
==
NAND_CMD_ERASE2
||
command
==
NAND_CMD_PAGEPROG
)
{
/* Second half of a command we already calculated */
cafe_writel
(
cafe
,
cafe
->
ctl2
|
0x100
|
command
,
NAND_CTRL2
);
ctl1
=
cafe
->
ctl1
;
cafe
->
ctl2
&=
~
(
1
<<
30
);
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Continue command, ctl1 %08x, #data %d
\n
"
,
cafe
->
ctl1
,
cafe
->
nr_data
);
goto
do_command
;
}
/* Reset ECC engine */
cafe_writel
(
cafe
,
0
,
NAND_CTRL2
);
/* Emulate NAND_CMD_READOOB on large-page chips */
if
(
mtd
->
writesize
>
512
&&
command
==
NAND_CMD_READOOB
)
{
column
+=
mtd
->
writesize
;
command
=
NAND_CMD_READ0
;
}
/* FIXME: Do we need to send read command before sending data
for small-page chips, to position the buffer correctly? */
if
(
column
!=
-
1
)
{
cafe_writel
(
cafe
,
column
,
NAND_ADDR1
);
adrbytes
=
2
;
if
(
page_addr
!=
-
1
)
goto
write_adr2
;
}
else
if
(
page_addr
!=
-
1
)
{
cafe_writel
(
cafe
,
page_addr
&
0xffff
,
NAND_ADDR1
);
page_addr
>>=
16
;
write_adr2:
cafe_writel
(
cafe
,
page_addr
,
NAND_ADDR2
);
adrbytes
+=
2
;
if
(
mtd
->
size
>
mtd
->
writesize
<<
16
)
adrbytes
++
;
}
cafe
->
data_pos
=
cafe
->
datalen
=
0
;
/* Set command valid bit */
ctl1
=
0x80000000
|
command
;
/* Set RD or WR bits as appropriate */
if
(
command
==
NAND_CMD_READID
||
command
==
NAND_CMD_STATUS
)
{
ctl1
|=
(
1
<<
26
);
/* rd */
/* Always 5 bytes, for now */
cafe
->
datalen
=
4
;
/* And one address cycle -- even for STATUS, since the controller doesn't work without */
adrbytes
=
1
;
}
else
if
(
command
==
NAND_CMD_READ0
||
command
==
NAND_CMD_READ1
||
command
==
NAND_CMD_READOOB
||
command
==
NAND_CMD_RNDOUT
)
{
ctl1
|=
1
<<
26
;
/* rd */
/* For now, assume just read to end of page */
cafe
->
datalen
=
mtd
->
writesize
+
mtd
->
oobsize
-
column
;
}
else
if
(
command
==
NAND_CMD_SEQIN
)
ctl1
|=
1
<<
25
;
/* wr */
/* Set number of address bytes */
if
(
adrbytes
)
ctl1
|=
((
adrbytes
-
1
)
|
8
)
<<
27
;
if
(
command
==
NAND_CMD_SEQIN
||
command
==
NAND_CMD_ERASE1
)
{
/* Ignore the first command of a pair; the hardware
deals with them both at once, later */
cafe
->
ctl1
=
ctl1
;
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Setup for delayed command, ctl1 %08x, dlen %x
\n
"
,
cafe
->
ctl1
,
cafe
->
datalen
);
return
;
}
/* RNDOUT and READ0 commands need a following byte */
if
(
command
==
NAND_CMD_RNDOUT
)
cafe_writel
(
cafe
,
cafe
->
ctl2
|
0x100
|
NAND_CMD_RNDOUTSTART
,
NAND_CTRL2
);
else
if
(
command
==
NAND_CMD_READ0
&&
mtd
->
writesize
>
512
)
cafe_writel
(
cafe
,
cafe
->
ctl2
|
0x100
|
NAND_CMD_READSTART
,
NAND_CTRL2
);
do_command:
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"dlen %x, ctl1 %x, ctl2 %x
\n
"
,
cafe
->
datalen
,
ctl1
,
cafe_readl
(
cafe
,
NAND_CTRL2
));
/* NB: The datasheet lies -- we really should be subtracting 1 here */
cafe_writel
(
cafe
,
cafe
->
datalen
,
NAND_DATA_LEN
);
cafe_writel
(
cafe
,
0x90000000
,
NAND_IRQ
);
if
(
usedma
&&
(
ctl1
&
(
3
<<
25
)))
{
uint32_t
dmactl
=
0xc0000000
+
cafe
->
datalen
;
/* If WR or RD bits set, set up DMA */
if
(
ctl1
&
(
1
<<
26
))
{
/* It's a read */
dmactl
|=
(
1
<<
29
);
/* ... so it's done when the DMA is done, not just
the command. */
doneint
=
0x10000000
;
}
cafe_writel
(
cafe
,
dmactl
,
NAND_DMA_CTRL
);
}
cafe
->
datalen
=
0
;
if
(
unlikely
(
regdebug
))
{
int
i
;
printk
(
"About to write command %08x to register 0
\n
"
,
ctl1
);
for
(
i
=
4
;
i
<
0x5c
;
i
+=
4
)
printk
(
"Register %x: %08x
\n
"
,
i
,
readl
(
cafe
->
mmio
+
i
));
}
cafe_writel
(
cafe
,
ctl1
,
NAND_CTRL1
);
/* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
ndelay
(
100
);
if
(
1
)
{
int
c
=
500000
;
uint32_t
irqs
;
while
(
c
--
)
{
irqs
=
cafe_readl
(
cafe
,
NAND_IRQ
);
if
(
irqs
&
doneint
)
break
;
udelay
(
1
);
if
(
!
(
c
%
100000
))
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Wait for ready, IRQ %x
\n
"
,
irqs
);
cpu_relax
();
}
cafe_writel
(
cafe
,
doneint
,
NAND_IRQ
);
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Command %x completed after %d usec, irqs %x (%x)
\n
"
,
command
,
500000
-
c
,
irqs
,
cafe_readl
(
cafe
,
NAND_IRQ
));
}
WARN_ON
(
cafe
->
ctl2
&
(
1
<<
30
));
switch
(
command
)
{
case
NAND_CMD_CACHEDPROG
:
case
NAND_CMD_PAGEPROG
:
case
NAND_CMD_ERASE1
:
case
NAND_CMD_ERASE2
:
case
NAND_CMD_SEQIN
:
case
NAND_CMD_RNDIN
:
case
NAND_CMD_STATUS
:
case
NAND_CMD_DEPLETE1
:
case
NAND_CMD_RNDOUT
:
case
NAND_CMD_STATUS_ERROR
:
case
NAND_CMD_STATUS_ERROR0
:
case
NAND_CMD_STATUS_ERROR1
:
case
NAND_CMD_STATUS_ERROR2
:
case
NAND_CMD_STATUS_ERROR3
:
cafe_writel
(
cafe
,
cafe
->
ctl2
,
NAND_CTRL2
);
return
;
}
nand_wait_ready
(
mtd
);
cafe_writel
(
cafe
,
cafe
->
ctl2
,
NAND_CTRL2
);
}
static
void
cafe_select_chip
(
struct
mtd_info
*
mtd
,
int
chipnr
)
{
//struct cafe_priv *cafe = mtd->priv;
// cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr);
}
static
int
cafe_nand_interrupt
(
int
irq
,
void
*
id
,
struct
pt_regs
*
regs
)
{
struct
mtd_info
*
mtd
=
id
;
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
uint32_t
irqs
=
cafe_readl
(
cafe
,
NAND_IRQ
);
cafe_writel
(
cafe
,
irqs
&
~
0x90000000
,
NAND_IRQ
);
if
(
!
irqs
)
return
IRQ_NONE
;
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"irq, bits %x (%x)
\n
"
,
irqs
,
cafe_readl
(
cafe
,
NAND_IRQ
));
return
IRQ_HANDLED
;
}
static
void
cafe_nand_bug
(
struct
mtd_info
*
mtd
)
{
BUG
();
}
static
int
cafe_nand_write_oob
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
chip
,
int
page
)
{
int
status
=
0
;
chip
->
cmdfunc
(
mtd
,
NAND_CMD_SEQIN
,
mtd
->
writesize
,
page
);
chip
->
write_buf
(
mtd
,
chip
->
oob_poi
,
mtd
->
oobsize
);
chip
->
cmdfunc
(
mtd
,
NAND_CMD_PAGEPROG
,
-
1
,
-
1
);
status
=
chip
->
waitfunc
(
mtd
,
chip
);
return
status
&
NAND_STATUS_FAIL
?
-
EIO
:
0
;
}
/* Don't use -- use nand_read_oob_std for now */
static
int
cafe_nand_read_oob
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
chip
,
int
page
,
int
sndcmd
)
{
chip
->
cmdfunc
(
mtd
,
NAND_CMD_READOOB
,
0
,
page
);
chip
->
read_buf
(
mtd
,
chip
->
oob_poi
,
mtd
->
oobsize
);
return
1
;
}
/**
* cafe_nand_read_page_syndrome - {REPLACABLE] hardware ecc syndrom based page read
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
*
* The hw generator calculates the error syndrome automatically. Therefor
* we need a special oob layout and handling.
*/
static
int
cafe_nand_read_page
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
chip
,
uint8_t
*
buf
)
{
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"ECC result %08x SYN1,2 %08x
\n
"
,
cafe_readl
(
cafe
,
NAND_ECC_RESULT
),
cafe_readl
(
cafe
,
NAND_ECC_SYN01
));
chip
->
read_buf
(
mtd
,
buf
,
mtd
->
writesize
);
chip
->
read_buf
(
mtd
,
chip
->
oob_poi
,
mtd
->
oobsize
);
if
(
checkecc
&&
cafe_readl
(
cafe
,
NAND_ECC_RESULT
)
&
(
1
<<
18
))
{
unsigned
short
syn
[
8
];
int
i
;
for
(
i
=
0
;
i
<
8
;
i
+=
2
)
{
uint32_t
tmp
=
cafe_readl
(
cafe
,
NAND_ECC_SYN01
+
(
i
*
2
));
syn
[
i
]
=
tmp
&
0xfff
;
syn
[
i
+
1
]
=
(
tmp
>>
16
)
&
0xfff
;
}
if
((
i
=
cafe_correct_ecc
(
buf
,
syn
))
<
0
)
{
dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Failed to correct ECC at %08x
\n
"
,
cafe_readl
(
cafe
,
NAND_ADDR2
)
*
2048
);
for
(
i
=
0
;
i
<
0x5c
;
i
+=
4
)
printk
(
"Register %x: %08x
\n
"
,
i
,
readl
(
cafe
->
mmio
+
i
));
mtd
->
ecc_stats
.
failed
++
;
}
else
{
dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Corrected %d symbol errors
\n
"
,
i
);
mtd
->
ecc_stats
.
corrected
+=
i
;
}
}
return
0
;
}
static
struct
nand_ecclayout
cafe_oobinfo_2048
=
{
.
eccbytes
=
14
,
.
eccpos
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
},
.
oobfree
=
{{
14
,
50
}}
};
/* Ick. The BBT code really ought to be able to work this bit out
for itself from the above, at least for the 2KiB case */
static
uint8_t
cafe_bbt_pattern_2048
[]
=
{
'B'
,
'b'
,
't'
,
'0'
};
static
uint8_t
cafe_mirror_pattern_2048
[]
=
{
'1'
,
't'
,
'b'
,
'B'
};
static
uint8_t
cafe_bbt_pattern_512
[]
=
{
0xBB
};
static
uint8_t
cafe_mirror_pattern_512
[]
=
{
0xBC
};
static
struct
nand_bbt_descr
cafe_bbt_main_descr_2048
=
{
.
options
=
NAND_BBT_LASTBLOCK
|
NAND_BBT_CREATE
|
NAND_BBT_WRITE
|
NAND_BBT_2BIT
|
NAND_BBT_VERSION
|
NAND_BBT_PERCHIP
,
.
offs
=
14
,
.
len
=
4
,
.
veroffs
=
18
,
.
maxblocks
=
4
,
.
pattern
=
cafe_bbt_pattern_2048
};
static
struct
nand_bbt_descr
cafe_bbt_mirror_descr_2048
=
{
.
options
=
NAND_BBT_LASTBLOCK
|
NAND_BBT_CREATE
|
NAND_BBT_WRITE
|
NAND_BBT_2BIT
|
NAND_BBT_VERSION
|
NAND_BBT_PERCHIP
,
.
offs
=
14
,
.
len
=
4
,
.
veroffs
=
18
,
.
maxblocks
=
4
,
.
pattern
=
cafe_mirror_pattern_2048
};
static
struct
nand_ecclayout
cafe_oobinfo_512
=
{
.
eccbytes
=
14
,
.
eccpos
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
},
.
oobfree
=
{{
14
,
2
}}
};
static
struct
nand_bbt_descr
cafe_bbt_main_descr_512
=
{
.
options
=
NAND_BBT_LASTBLOCK
|
NAND_BBT_CREATE
|
NAND_BBT_WRITE
|
NAND_BBT_2BIT
|
NAND_BBT_VERSION
|
NAND_BBT_PERCHIP
,
.
offs
=
14
,
.
len
=
1
,
.
veroffs
=
15
,
.
maxblocks
=
4
,
.
pattern
=
cafe_bbt_pattern_512
};
static
struct
nand_bbt_descr
cafe_bbt_mirror_descr_512
=
{
.
options
=
NAND_BBT_LASTBLOCK
|
NAND_BBT_CREATE
|
NAND_BBT_WRITE
|
NAND_BBT_2BIT
|
NAND_BBT_VERSION
|
NAND_BBT_PERCHIP
,
.
offs
=
14
,
.
len
=
1
,
.
veroffs
=
15
,
.
maxblocks
=
4
,
.
pattern
=
cafe_mirror_pattern_512
};
static
void
cafe_nand_write_page_lowlevel
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
chip
,
const
uint8_t
*
buf
)
{
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
chip
->
write_buf
(
mtd
,
buf
,
mtd
->
writesize
);
chip
->
write_buf
(
mtd
,
chip
->
oob_poi
,
mtd
->
oobsize
);
/* Set up ECC autogeneration */
cafe
->
ctl2
|=
(
1
<<
30
);
}
static
int
cafe_nand_write_page
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
chip
,
const
uint8_t
*
buf
,
int
page
,
int
cached
,
int
raw
)
{
int
status
;
chip
->
cmdfunc
(
mtd
,
NAND_CMD_SEQIN
,
0x00
,
page
);
if
(
unlikely
(
raw
))
chip
->
ecc
.
write_page_raw
(
mtd
,
chip
,
buf
);
else
chip
->
ecc
.
write_page
(
mtd
,
chip
,
buf
);
/*
* Cached progamming disabled for now, Not sure if its worth the
* trouble. The speed gain is not very impressive. (2.3->2.6Mib/s)
*/
cached
=
0
;
if
(
!
cached
||
!
(
chip
->
options
&
NAND_CACHEPRG
))
{
chip
->
cmdfunc
(
mtd
,
NAND_CMD_PAGEPROG
,
-
1
,
-
1
);
status
=
chip
->
waitfunc
(
mtd
,
chip
);
/*
* See if operation failed and additional status checks are
* available
*/
if
((
status
&
NAND_STATUS_FAIL
)
&&
(
chip
->
errstat
))
status
=
chip
->
errstat
(
mtd
,
chip
,
FL_WRITING
,
status
,
page
);
if
(
status
&
NAND_STATUS_FAIL
)
return
-
EIO
;
}
else
{
chip
->
cmdfunc
(
mtd
,
NAND_CMD_CACHEDPROG
,
-
1
,
-
1
);
status
=
chip
->
waitfunc
(
mtd
,
chip
);
}
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
/* Send command to read back the data */
chip
->
cmdfunc
(
mtd
,
NAND_CMD_READ0
,
0
,
page
);
if
(
chip
->
verify_buf
(
mtd
,
buf
,
mtd
->
writesize
))
return
-
EIO
;
#endif
return
0
;
}
static
int
cafe_nand_block_bad
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
int
getchip
)
{
return
0
;
}
static
int
__devinit
cafe_nand_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
struct
mtd_info
*
mtd
;
struct
cafe_priv
*
cafe
;
uint32_t
ctrl
;
int
err
=
0
;
err
=
pci_enable_device
(
pdev
);
if
(
err
)
return
err
;
pci_set_master
(
pdev
);
mtd
=
kzalloc
(
sizeof
(
*
mtd
)
+
sizeof
(
struct
cafe_priv
),
GFP_KERNEL
);
if
(
!
mtd
)
{
dev_warn
(
&
pdev
->
dev
,
"failed to alloc mtd_info
\n
"
);
return
-
ENOMEM
;
}
cafe
=
(
void
*
)(
&
mtd
[
1
]);
mtd
->
priv
=
cafe
;
mtd
->
owner
=
THIS_MODULE
;
cafe
->
pdev
=
pdev
;
cafe
->
mmio
=
pci_iomap
(
pdev
,
0
,
0
);
if
(
!
cafe
->
mmio
)
{
dev_warn
(
&
pdev
->
dev
,
"failed to iomap
\n
"
);
err
=
-
ENOMEM
;
goto
out_free_mtd
;
}
cafe
->
dmabuf
=
dma_alloc_coherent
(
&
cafe
->
pdev
->
dev
,
2112
+
sizeof
(
struct
nand_buffers
),
&
cafe
->
dmaaddr
,
GFP_KERNEL
);
if
(
!
cafe
->
dmabuf
)
{
err
=
-
ENOMEM
;
goto
out_ior
;
}
cafe
->
nand
.
buffers
=
(
void
*
)
cafe
->
dmabuf
+
2112
;
cafe
->
nand
.
cmdfunc
=
cafe_nand_cmdfunc
;
cafe
->
nand
.
dev_ready
=
cafe_device_ready
;
cafe
->
nand
.
read_byte
=
cafe_read_byte
;
cafe
->
nand
.
read_buf
=
cafe_read_buf
;
cafe
->
nand
.
write_buf
=
cafe_write_buf
;
cafe
->
nand
.
select_chip
=
cafe_select_chip
;
cafe
->
nand
.
chip_delay
=
0
;
/* Enable the following for a flash based bad block table */
cafe
->
nand
.
options
=
NAND_USE_FLASH_BBT
|
NAND_NO_AUTOINCR
|
NAND_OWN_BUFFERS
;
if
(
skipbbt
)
{
cafe
->
nand
.
options
|=
NAND_SKIP_BBTSCAN
;
cafe
->
nand
.
block_bad
=
cafe_nand_block_bad
;
}
/* Start off by resetting the NAND controller completely */
cafe_writel
(
cafe
,
1
,
NAND_RESET
);
cafe_writel
(
cafe
,
0
,
NAND_RESET
);
cafe_writel
(
cafe
,
0xffffffff
,
NAND_IRQ_MASK
);
/* Timings from Marvell's test code (not verified or calculated by us) */
if
(
!
slowtiming
)
{
cafe_writel
(
cafe
,
0x01010a0a
,
NAND_TIMING1
);
cafe_writel
(
cafe
,
0x24121212
,
NAND_TIMING2
);
cafe_writel
(
cafe
,
0x11000000
,
NAND_TIMING3
);
}
else
{
cafe_writel
(
cafe
,
0xffffffff
,
NAND_TIMING1
);
cafe_writel
(
cafe
,
0xffffffff
,
NAND_TIMING2
);
cafe_writel
(
cafe
,
0xffffffff
,
NAND_TIMING3
);
}
cafe_writel
(
cafe
,
0xffffffff
,
NAND_IRQ_MASK
);
err
=
request_irq
(
pdev
->
irq
,
&
cafe_nand_interrupt
,
SA_SHIRQ
,
"CAFE NAND"
,
mtd
);
if
(
err
)
{
dev_warn
(
&
pdev
->
dev
,
"Could not register IRQ %d
\n
"
,
pdev
->
irq
);
goto
out_free_dma
;
}
#if 1
/* Disable master reset, enable NAND clock */
ctrl
=
cafe_readl
(
cafe
,
GLOBAL_CTRL
);
ctrl
&=
0xffffeff0
;
ctrl
|=
0x00007000
;
cafe_writel
(
cafe
,
ctrl
|
0x05
,
GLOBAL_CTRL
);
cafe_writel
(
cafe
,
ctrl
|
0x0a
,
GLOBAL_CTRL
);
cafe_writel
(
cafe
,
0
,
NAND_DMA_CTRL
);
cafe_writel
(
cafe
,
0x7006
,
GLOBAL_CTRL
);
cafe_writel
(
cafe
,
0x700a
,
GLOBAL_CTRL
);
/* Set up DMA address */
cafe_writel
(
cafe
,
cafe
->
dmaaddr
&
0xffffffff
,
NAND_DMA_ADDR0
);
if
(
sizeof
(
cafe
->
dmaaddr
)
>
4
)
/* Shift in two parts to shut the compiler up */
cafe_writel
(
cafe
,
(
cafe
->
dmaaddr
>>
16
)
>>
16
,
NAND_DMA_ADDR1
);
else
cafe_writel
(
cafe
,
0
,
NAND_DMA_ADDR1
);
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Set DMA address to %x (virt %p)
\n
"
,
cafe_readl
(
cafe
,
NAND_DMA_ADDR0
),
cafe
->
dmabuf
);
/* Enable NAND IRQ in global IRQ mask register */
cafe_writel
(
cafe
,
0x80000007
,
GLOBAL_IRQ_MASK
);
cafe_dev_dbg
(
&
cafe
->
pdev
->
dev
,
"Control %x, IRQ mask %x
\n
"
,
cafe_readl
(
cafe
,
GLOBAL_CTRL
),
cafe_readl
(
cafe
,
GLOBAL_IRQ_MASK
));
#endif
#if 1
mtd
->
writesize
=
2048
;
mtd
->
oobsize
=
0x40
;
memset
(
cafe
->
dmabuf
,
0x5a
,
2112
);
cafe
->
nand
.
cmdfunc
(
mtd
,
NAND_CMD_READID
,
0
,
-
1
);
cafe
->
nand
.
read_byte
(
mtd
);
cafe
->
nand
.
read_byte
(
mtd
);
cafe
->
nand
.
read_byte
(
mtd
);
cafe
->
nand
.
read_byte
(
mtd
);
cafe
->
nand
.
read_byte
(
mtd
);
#endif
#if 0
cafe->nand.cmdfunc(mtd, NAND_CMD_READ0, 0, 0);
// nand_wait_ready(mtd);
cafe->nand.read_byte(mtd);
cafe->nand.read_byte(mtd);
cafe->nand.read_byte(mtd);
cafe->nand.read_byte(mtd);
#endif
#if 0
writel(0x84600070, cafe->mmio);
udelay(10);
cafe_dev_dbg(&cafe->pdev->dev, "Status %x\n", cafe_readl(cafe, NAND_NONMEM));
#endif
/* Scan to find existance of the device */
if
(
nand_scan_ident
(
mtd
,
1
))
{
err
=
-
ENXIO
;
goto
out_irq
;
}
cafe
->
ctl2
=
1
<<
27
;
/* Reed-Solomon ECC */
if
(
mtd
->
writesize
==
2048
)
cafe
->
ctl2
|=
1
<<
29
;
/* 2KiB page size */
/* Set up ECC according to the type of chip we found */
if
(
mtd
->
writesize
==
2048
)
{
cafe
->
nand
.
ecc
.
layout
=
&
cafe_oobinfo_2048
;
cafe
->
nand
.
bbt_td
=
&
cafe_bbt_main_descr_2048
;
cafe
->
nand
.
bbt_md
=
&
cafe_bbt_mirror_descr_2048
;
}
else
if
(
mtd
->
writesize
==
512
)
{
cafe
->
nand
.
ecc
.
layout
=
&
cafe_oobinfo_512
;
cafe
->
nand
.
bbt_td
=
&
cafe_bbt_main_descr_512
;
cafe
->
nand
.
bbt_md
=
&
cafe_bbt_mirror_descr_512
;
}
else
{
printk
(
KERN_WARNING
"Unexpected NAND flash writesize %d. Aborting
\n
"
,
mtd
->
writesize
);
goto
out_irq
;
}
cafe
->
nand
.
ecc
.
mode
=
NAND_ECC_HW_SYNDROME
;
cafe
->
nand
.
ecc
.
size
=
mtd
->
writesize
;
cafe
->
nand
.
ecc
.
bytes
=
14
;
cafe
->
nand
.
ecc
.
hwctl
=
(
void
*
)
cafe_nand_bug
;
cafe
->
nand
.
ecc
.
calculate
=
(
void
*
)
cafe_nand_bug
;
cafe
->
nand
.
ecc
.
correct
=
(
void
*
)
cafe_nand_bug
;
cafe
->
nand
.
write_page
=
cafe_nand_write_page
;
cafe
->
nand
.
ecc
.
write_page
=
cafe_nand_write_page_lowlevel
;
cafe
->
nand
.
ecc
.
write_oob
=
cafe_nand_write_oob
;
cafe
->
nand
.
ecc
.
read_page
=
cafe_nand_read_page
;
cafe
->
nand
.
ecc
.
read_oob
=
cafe_nand_read_oob
;
err
=
nand_scan_tail
(
mtd
);
if
(
err
)
goto
out_irq
;
pci_set_drvdata
(
pdev
,
mtd
);
add_mtd_device
(
mtd
);
goto
out
;
out_irq:
/* Disable NAND IRQ in global IRQ mask register */
cafe_writel
(
cafe
,
~
1
&
cafe_readl
(
cafe
,
GLOBAL_IRQ_MASK
),
GLOBAL_IRQ_MASK
);
free_irq
(
pdev
->
irq
,
mtd
);
out_free_dma:
dma_free_coherent
(
&
cafe
->
pdev
->
dev
,
2112
,
cafe
->
dmabuf
,
cafe
->
dmaaddr
);
out_ior:
pci_iounmap
(
pdev
,
cafe
->
mmio
);
out_free_mtd:
kfree
(
mtd
);
out:
return
err
;
}
static
void
__devexit
cafe_nand_remove
(
struct
pci_dev
*
pdev
)
{
struct
mtd_info
*
mtd
=
pci_get_drvdata
(
pdev
);
struct
cafe_priv
*
cafe
=
mtd
->
priv
;
del_mtd_device
(
mtd
);
/* Disable NAND IRQ in global IRQ mask register */
cafe_writel
(
cafe
,
~
1
&
cafe_readl
(
cafe
,
GLOBAL_IRQ_MASK
),
GLOBAL_IRQ_MASK
);
free_irq
(
pdev
->
irq
,
mtd
);
nand_release
(
mtd
);
pci_iounmap
(
pdev
,
cafe
->
mmio
);
dma_free_coherent
(
&
cafe
->
pdev
->
dev
,
2112
,
cafe
->
dmabuf
,
cafe
->
dmaaddr
);
kfree
(
mtd
);
}
static
struct
pci_device_id
cafe_nand_tbl
[]
=
{
{
0x11ab
,
0x4100
,
PCI_ANY_ID
,
PCI_ANY_ID
,
PCI_CLASS_MEMORY_FLASH
<<
8
,
0xFFFF0
}
};
MODULE_DEVICE_TABLE
(
pci
,
cafe_nand_tbl
);
static
struct
pci_driver
cafe_nand_pci_driver
=
{
.
name
=
"CAFÉ NAND"
,
.
id_table
=
cafe_nand_tbl
,
.
probe
=
cafe_nand_probe
,
.
remove
=
__devexit_p
(
cafe_nand_remove
),
#ifdef CONFIG_PMx
.
suspend
=
cafe_nand_suspend
,
.
resume
=
cafe_nand_resume
,
#endif
};
static
int
cafe_nand_init
(
void
)
{
return
pci_register_driver
(
&
cafe_nand_pci_driver
);
}
static
void
cafe_nand_exit
(
void
)
{
pci_unregister_driver
(
&
cafe_nand_pci_driver
);
}
module_init
(
cafe_nand_init
);
module_exit
(
cafe_nand_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"David Woodhouse <dwmw2@infradead.org>"
);
MODULE_DESCRIPTION
(
"NAND flash driver for OLPC CAFE chip"
);
/* Correct ECC for 2048 bytes of 0xff:
41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */
/* dwmw2's B-test board, in case of completely screwing it:
Bad eraseblock 2394 at 0x12b40000
Bad eraseblock 2627 at 0x14860000
Bad eraseblock 3349 at 0x1a2a0000
*/
drivers/mtd/nand/cafe_ecc.c
0 → 100644
View file @
1aaaeabf
/* Error correction for CAFÉ NAND controller
*
* © 2006 Marvell, Inc.
* Author: Tom Chiou
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
static
unsigned
short
gf4096_mul
(
unsigned
short
,
unsigned
short
);
static
unsigned
short
gf64_mul
(
unsigned
short
,
unsigned
short
);
static
unsigned
short
gf4096_inv
(
unsigned
short
);
static
unsigned
short
err_pos
(
unsigned
short
);
static
void
find_4bit_err_coefs
(
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
*
);
static
void
zero_4x5_col3
(
unsigned
short
[
4
][
5
]);
static
void
zero_4x5_col2
(
unsigned
short
[
4
][
5
]);
static
void
zero_4x5_col1
(
unsigned
short
[
4
][
5
]);
static
void
swap_4x5_rows
(
unsigned
short
[
4
][
5
],
int
,
int
,
int
);
static
void
swap_2x3_rows
(
unsigned
short
m
[
2
][
3
]);
static
void
solve_4x5
(
unsigned
short
m
[
4
][
5
],
unsigned
short
*
,
int
*
);
static
void
sort_coefs
(
int
*
,
unsigned
short
*
,
int
);
static
void
find_4bit_err_pats
(
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
*
);
static
void
find_3bit_err_coefs
(
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
*
);
static
void
zero_3x4_col2
(
unsigned
short
[
3
][
4
]);
static
void
zero_3x4_col1
(
unsigned
short
[
3
][
4
]);
static
void
swap_3x4_rows
(
unsigned
short
[
3
][
4
],
int
,
int
,
int
);
static
void
solve_3x4
(
unsigned
short
[
3
][
4
],
unsigned
short
*
,
int
*
);
static
void
find_3bit_err_pats
(
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
*
);
static
void
find_2bit_err_pats
(
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
*
);
static
void
find_2x2_soln
(
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
,
unsigned
short
*
);
static
void
solve_2x3
(
unsigned
short
[
2
][
3
],
unsigned
short
*
);
static
int
chk_no_err_only
(
unsigned
short
*
,
unsigned
short
*
);
static
int
chk_1_err_only
(
unsigned
short
*
,
unsigned
short
*
);
static
int
chk_2_err_only
(
unsigned
short
*
,
unsigned
short
*
);
static
int
chk_3_err_only
(
unsigned
short
*
,
unsigned
short
*
);
static
int
chk_4_err_only
(
unsigned
short
*
,
unsigned
short
*
);
static
unsigned
short
gf64_mul
(
unsigned
short
a
,
unsigned
short
b
)
{
unsigned
short
tmp1
,
tmp2
,
tmp3
,
tmp4
,
tmp5
;
unsigned
short
c_bit0
,
c_bit1
,
c_bit2
,
c_bit3
,
c_bit4
,
c_bit5
,
c
;
tmp1
=
((
a
)
^
(
a
>>
5
));
tmp2
=
((
a
>>
4
)
^
(
a
>>
5
));
tmp3
=
((
a
>>
3
)
^
(
a
>>
4
));
tmp4
=
((
a
>>
2
)
^
(
a
>>
3
));
tmp5
=
((
a
>>
1
)
^
(
a
>>
2
));
c_bit0
=
((
a
&
b
)
^
((
a
>>
5
)
&
(
b
>>
1
))
^
((
a
>>
4
)
&
(
b
>>
2
))
^
((
a
>>
3
)
&
(
b
>>
3
))
^
((
a
>>
2
)
&
(
b
>>
4
))
^
((
a
>>
1
)
&
(
b
>>
5
)))
&
0x1
;
c_bit1
=
(((
a
>>
1
)
&
b
)
^
(
tmp1
&
(
b
>>
1
))
^
(
tmp2
&
(
b
>>
2
))
^
(
tmp3
&
(
b
>>
3
))
^
(
tmp4
&
(
b
>>
4
))
^
(
tmp5
&
(
b
>>
5
)))
&
0x1
;
c_bit2
=
(((
a
>>
2
)
&
b
)
^
((
a
>>
1
)
&
(
b
>>
1
))
^
(
tmp1
&
(
b
>>
2
))
^
(
tmp2
&
(
b
>>
3
))
^
(
tmp3
&
(
b
>>
4
))
^
(
tmp4
&
(
b
>>
5
)))
&
0x1
;
c_bit3
=
(((
a
>>
3
)
&
b
)
^
((
a
>>
2
)
&
(
b
>>
1
))
^
((
a
>>
1
)
&
(
b
>>
2
))
^
(
tmp1
&
(
b
>>
3
))
^
(
tmp2
&
(
b
>>
4
))
^
(
tmp3
&
(
b
>>
5
)))
&
0x1
;
c_bit4
=
(((
a
>>
4
)
&
b
)
^
((
a
>>
3
)
&
(
b
>>
1
))
^
((
a
>>
2
)
&
(
b
>>
2
))
^
((
a
>>
1
)
&
(
b
>>
3
))
^
(
tmp1
&
(
b
>>
4
))
^
(
tmp2
&
(
b
>>
5
)))
&
0x1
;
c_bit5
=
(((
a
>>
5
)
&
b
)
^
((
a
>>
4
)
&
(
b
>>
1
))
^
((
a
>>
3
)
&
(
b
>>
2
))
^
((
a
>>
2
)
&
(
b
>>
3
))
^
((
a
>>
1
)
&
(
b
>>
4
))
^
(
tmp1
&
(
b
>>
5
)))
&
0x1
;
c
=
c_bit0
|
(
c_bit1
<<
1
)
|
(
c_bit2
<<
2
)
|
(
c_bit3
<<
3
)
|
(
c_bit4
<<
4
)
|
(
c_bit5
<<
5
);
return
c
;
}
static
unsigned
short
gf4096_mul
(
unsigned
short
a
,
unsigned
short
b
)
{
unsigned
short
ah
,
al
,
bh
,
bl
,
alxah
,
blxbh
,
ablh
,
albl
,
ahbh
,
ahbhB
,
c
;
ah
=
(
a
>>
6
)
&
0x3f
;
al
=
a
&
0x3f
;
bh
=
(
b
>>
6
)
&
0x3f
;
bl
=
b
&
0x3f
;
alxah
=
al
^
ah
;
blxbh
=
bl
^
bh
;
ablh
=
gf64_mul
(
alxah
,
blxbh
);
albl
=
gf64_mul
(
al
,
bl
);
ahbh
=
gf64_mul
(
ah
,
bh
);
ahbhB
=
((
ahbh
&
0x1
)
<<
5
)
|
((
ahbh
&
0x20
)
>>
1
)
|
((
ahbh
&
0x10
)
>>
1
)
|
((
ahbh
&
0x8
)
>>
1
)
|
((
ahbh
&
0x4
)
>>
1
)
|
(((
ahbh
>>
1
)
^
ahbh
)
&
0x1
);
c
=
((
ablh
^
albl
)
<<
6
)
|
(
ahbhB
^
albl
);
return
c
;
}
static
void
find_2bit_err_pats
(
unsigned
short
s0
,
unsigned
short
s1
,
unsigned
short
r0
,
unsigned
short
r1
,
unsigned
short
*
pats
)
{
find_2x2_soln
(
0x1
,
0x1
,
r0
,
r1
,
s0
,
s1
,
pats
);
}
static
void
find_3bit_err_coefs
(
unsigned
short
s0
,
unsigned
short
s1
,
unsigned
short
s2
,
unsigned
short
s3
,
unsigned
short
s4
,
unsigned
short
s5
,
unsigned
short
*
coefs
)
{
unsigned
short
m
[
3
][
4
];
int
row_order
[
3
];
row_order
[
0
]
=
0
;
row_order
[
1
]
=
1
;
row_order
[
2
]
=
2
;
m
[
0
][
0
]
=
s2
;
m
[
0
][
1
]
=
s1
;
m
[
0
][
2
]
=
s0
;
m
[
0
][
3
]
=
s3
;
m
[
1
][
0
]
=
s3
;
m
[
1
][
1
]
=
s2
;
m
[
1
][
2
]
=
s1
;
m
[
1
][
3
]
=
s4
;
m
[
2
][
0
]
=
s4
;
m
[
2
][
1
]
=
s3
;
m
[
2
][
2
]
=
s2
;
m
[
2
][
3
]
=
s5
;
if
(
m
[
0
][
2
]
!=
0x0
)
{
zero_3x4_col2
(
m
);
}
else
if
(
m
[
1
][
2
]
!=
0x0
)
{
swap_3x4_rows
(
m
,
0
,
1
,
4
);
zero_3x4_col2
(
m
);
}
else
if
(
m
[
2
][
2
]
!=
0x0
)
{
swap_3x4_rows
(
m
,
0
,
2
,
4
);
zero_3x4_col2
(
m
);
}
else
{
printk
(
KERN_ERR
"Error: find_3bit_err_coefs, s0,s1,s2 all zeros!
\n
"
);
}
if
(
m
[
1
][
1
]
!=
0x0
)
{
zero_3x4_col1
(
m
);
}
else
if
(
m
[
2
][
1
]
!=
0x0
)
{
swap_3x4_rows
(
m
,
1
,
2
,
4
);
zero_3x4_col1
(
m
);
}
else
{
printk
(
KERN_ERR
"Error: find_3bit_err_coefs, cannot resolve col 1!
\n
"
);
}
/* solve coefs */
solve_3x4
(
m
,
coefs
,
row_order
);
}
static
void
zero_3x4_col2
(
unsigned
short
m
[
3
][
4
])
{
unsigned
short
minv1
,
minv2
;
minv1
=
gf4096_mul
(
m
[
1
][
2
],
gf4096_inv
(
m
[
0
][
2
]));
minv2
=
gf4096_mul
(
m
[
2
][
2
],
gf4096_inv
(
m
[
0
][
2
]));
m
[
1
][
0
]
=
m
[
1
][
0
]
^
gf4096_mul
(
m
[
0
][
0
],
minv1
);
m
[
1
][
1
]
=
m
[
1
][
1
]
^
gf4096_mul
(
m
[
0
][
1
],
minv1
);
m
[
1
][
3
]
=
m
[
1
][
3
]
^
gf4096_mul
(
m
[
0
][
3
],
minv1
);
m
[
2
][
0
]
=
m
[
2
][
0
]
^
gf4096_mul
(
m
[
0
][
0
],
minv2
);
m
[
2
][
1
]
=
m
[
2
][
1
]
^
gf4096_mul
(
m
[
0
][
1
],
minv2
);
m
[
2
][
3
]
=
m
[
2
][
3
]
^
gf4096_mul
(
m
[
0
][
3
],
minv2
);
}
static
void
zero_3x4_col1
(
unsigned
short
m
[
3
][
4
])
{
unsigned
short
minv
;
minv
=
gf4096_mul
(
m
[
2
][
1
],
gf4096_inv
(
m
[
1
][
1
]));
m
[
2
][
0
]
=
m
[
2
][
0
]
^
gf4096_mul
(
m
[
1
][
0
],
minv
);
m
[
2
][
3
]
=
m
[
2
][
3
]
^
gf4096_mul
(
m
[
1
][
3
],
minv
);
}
static
void
swap_3x4_rows
(
unsigned
short
m
[
3
][
4
],
int
i
,
int
j
,
int
col_width
)
{
unsigned
short
tmp0
;
int
cnt
;
for
(
cnt
=
0
;
cnt
<
col_width
;
cnt
++
)
{
tmp0
=
m
[
i
][
cnt
];
m
[
i
][
cnt
]
=
m
[
j
][
cnt
];
m
[
j
][
cnt
]
=
tmp0
;
}
}
static
void
solve_3x4
(
unsigned
short
m
[
3
][
4
],
unsigned
short
*
coefs
,
int
*
row_order
)
{
unsigned
short
tmp
[
3
];
tmp
[
0
]
=
gf4096_mul
(
m
[
2
][
3
],
gf4096_inv
(
m
[
2
][
0
]));
tmp
[
1
]
=
gf4096_mul
((
gf4096_mul
(
tmp
[
0
],
m
[
1
][
0
])
^
m
[
1
][
3
]),
gf4096_inv
(
m
[
1
][
1
]));
tmp
[
2
]
=
gf4096_mul
((
gf4096_mul
(
tmp
[
0
],
m
[
0
][
0
])
^
gf4096_mul
(
tmp
[
1
],
m
[
0
][
1
])
^
m
[
0
][
3
]),
gf4096_inv
(
m
[
0
][
2
]));
sort_coefs
(
row_order
,
tmp
,
3
);
coefs
[
0
]
=
tmp
[
0
];
coefs
[
1
]
=
tmp
[
1
];
coefs
[
2
]
=
tmp
[
2
];
}
static
void
find_3bit_err_pats
(
unsigned
short
s0
,
unsigned
short
s1
,
unsigned
short
s2
,
unsigned
short
r0
,
unsigned
short
r1
,
unsigned
short
r2
,
unsigned
short
*
pats
)
{
find_2x2_soln
(
r0
^
r2
,
r1
^
r2
,
gf4096_mul
(
r0
,
r0
^
r2
),
gf4096_mul
(
r1
,
r1
^
r2
),
gf4096_mul
(
s0
,
r2
)
^
s1
,
gf4096_mul
(
s1
,
r2
)
^
s2
,
pats
);
pats
[
2
]
=
s0
^
pats
[
0
]
^
pats
[
1
];
}
static
void
find_4bit_err_coefs
(
unsigned
short
s0
,
unsigned
short
s1
,
unsigned
short
s2
,
unsigned
short
s3
,
unsigned
short
s4
,
unsigned
short
s5
,
unsigned
short
s6
,
unsigned
short
s7
,
unsigned
short
*
coefs
)
{
unsigned
short
m
[
4
][
5
];
int
row_order
[
4
];
row_order
[
0
]
=
0
;
row_order
[
1
]
=
1
;
row_order
[
2
]
=
2
;
row_order
[
3
]
=
3
;
m
[
0
][
0
]
=
s3
;
m
[
0
][
1
]
=
s2
;
m
[
0
][
2
]
=
s1
;
m
[
0
][
3
]
=
s0
;
m
[
0
][
4
]
=
s4
;
m
[
1
][
0
]
=
s4
;
m
[
1
][
1
]
=
s3
;
m
[
1
][
2
]
=
s2
;
m
[
1
][
3
]
=
s1
;
m
[
1
][
4
]
=
s5
;
m
[
2
][
0
]
=
s5
;
m
[
2
][
1
]
=
s4
;
m
[
2
][
2
]
=
s3
;
m
[
2
][
3
]
=
s2
;
m
[
2
][
4
]
=
s6
;
m
[
3
][
0
]
=
s6
;
m
[
3
][
1
]
=
s5
;
m
[
3
][
2
]
=
s4
;
m
[
3
][
3
]
=
s3
;
m
[
3
][
4
]
=
s7
;
if
(
m
[
0
][
3
]
!=
0x0
)
{
zero_4x5_col3
(
m
);
}
else
if
(
m
[
1
][
3
]
!=
0x0
)
{
swap_4x5_rows
(
m
,
0
,
1
,
5
);
zero_4x5_col3
(
m
);
}
else
if
(
m
[
2
][
3
]
!=
0x0
)
{
swap_4x5_rows
(
m
,
0
,
2
,
5
);
zero_4x5_col3
(
m
);
}
else
if
(
m
[
3
][
3
]
!=
0x0
)
{
swap_4x5_rows
(
m
,
0
,
3
,
5
);
zero_4x5_col3
(
m
);
}
else
{
printk
(
KERN_ERR
"Error: find_4bit_err_coefs, s0,s1,s2,s3 all zeros!
\n
"
);
}
if
(
m
[
1
][
2
]
!=
0x0
)
{
zero_4x5_col2
(
m
);
}
else
if
(
m
[
2
][
2
]
!=
0x0
)
{
swap_4x5_rows
(
m
,
1
,
2
,
5
);
zero_4x5_col2
(
m
);
}
else
if
(
m
[
3
][
2
]
!=
0x0
)
{
swap_4x5_rows
(
m
,
1
,
3
,
5
);
zero_4x5_col2
(
m
);
}
else
{
printk
(
KERN_ERR
"Error: find_4bit_err_coefs, cannot resolve col 2!
\n
"
);
}
if
(
m
[
2
][
1
]
!=
0x0
)
{
zero_4x5_col1
(
m
);
}
else
if
(
m
[
3
][
1
]
!=
0x0
)
{
swap_4x5_rows
(
m
,
2
,
3
,
5
);
zero_4x5_col1
(
m
);
}
else
{
printk
(
KERN_ERR
"Error: find_4bit_err_coefs, cannot resolve col 1!
\n
"
);
}
solve_4x5
(
m
,
coefs
,
row_order
);
}
static
void
zero_4x5_col3
(
unsigned
short
m
[
4
][
5
])
{
unsigned
short
minv1
,
minv2
,
minv3
;
minv1
=
gf4096_mul
(
m
[
1
][
3
],
gf4096_inv
(
m
[
0
][
3
]));
minv2
=
gf4096_mul
(
m
[
2
][
3
],
gf4096_inv
(
m
[
0
][
3
]));
minv3
=
gf4096_mul
(
m
[
3
][
3
],
gf4096_inv
(
m
[
0
][
3
]));
m
[
1
][
0
]
=
m
[
1
][
0
]
^
gf4096_mul
(
m
[
0
][
0
],
minv1
);
m
[
1
][
1
]
=
m
[
1
][
1
]
^
gf4096_mul
(
m
[
0
][
1
],
minv1
);
m
[
1
][
2
]
=
m
[
1
][
2
]
^
gf4096_mul
(
m
[
0
][
2
],
minv1
);
m
[
1
][
4
]
=
m
[
1
][
4
]
^
gf4096_mul
(
m
[
0
][
4
],
minv1
);
m
[
2
][
0
]
=
m
[
2
][
0
]
^
gf4096_mul
(
m
[
0
][
0
],
minv2
);
m
[
2
][
1
]
=
m
[
2
][
1
]
^
gf4096_mul
(
m
[
0
][
1
],
minv2
);
m
[
2
][
2
]
=
m
[
2
][
2
]
^
gf4096_mul
(
m
[
0
][
2
],
minv2
);
m
[
2
][
4
]
=
m
[
2
][
4
]
^
gf4096_mul
(
m
[
0
][
4
],
minv2
);
m
[
3
][
0
]
=
m
[
3
][
0
]
^
gf4096_mul
(
m
[
0
][
0
],
minv3
);
m
[
3
][
1
]
=
m
[
3
][
1
]
^
gf4096_mul
(
m
[
0
][
1
],
minv3
);
m
[
3
][
2
]
=
m
[
3
][
2
]
^
gf4096_mul
(
m
[
0
][
2
],
minv3
);
m
[
3
][
4
]
=
m
[
3
][
4
]
^
gf4096_mul
(
m
[
0
][
4
],
minv3
);
}
static
void
zero_4x5_col2
(
unsigned
short
m
[
4
][
5
])
{
unsigned
short
minv2
,
minv3
;
minv2
=
gf4096_mul
(
m
[
2
][
2
],
gf4096_inv
(
m
[
1
][
2
]));
minv3
=
gf4096_mul
(
m
[
3
][
2
],
gf4096_inv
(
m
[
1
][
2
]));
m
[
2
][
0
]
=
m
[
2
][
0
]
^
gf4096_mul
(
m
[
1
][
0
],
minv2
);
m
[
2
][
1
]
=
m
[
2
][
1
]
^
gf4096_mul
(
m
[
1
][
1
],
minv2
);
m
[
2
][
4
]
=
m
[
2
][
4
]
^
gf4096_mul
(
m
[
1
][
4
],
minv2
);
m
[
3
][
0
]
=
m
[
3
][
0
]
^
gf4096_mul
(
m
[
1
][
0
],
minv3
);
m
[
3
][
1
]
=
m
[
3
][
1
]
^
gf4096_mul
(
m
[
1
][
1
],
minv3
);
m
[
3
][
4
]
=
m
[
3
][
4
]
^
gf4096_mul
(
m
[
1
][
4
],
minv3
);
}
static
void
zero_4x5_col1
(
unsigned
short
m
[
4
][
5
])
{
unsigned
short
minv
;
minv
=
gf4096_mul
(
m
[
3
][
1
],
gf4096_inv
(
m
[
2
][
1
]));
m
[
3
][
0
]
=
m
[
3
][
0
]
^
gf4096_mul
(
m
[
2
][
0
],
minv
);
m
[
3
][
4
]
=
m
[
3
][
4
]
^
gf4096_mul
(
m
[
2
][
4
],
minv
);
}
static
void
swap_4x5_rows
(
unsigned
short
m
[
4
][
5
],
int
i
,
int
j
,
int
col_width
)
{
unsigned
short
tmp0
;
int
cnt
;
for
(
cnt
=
0
;
cnt
<
col_width
;
cnt
++
)
{
tmp0
=
m
[
i
][
cnt
];
m
[
i
][
cnt
]
=
m
[
j
][
cnt
];
m
[
j
][
cnt
]
=
tmp0
;
}
}
static
void
solve_4x5
(
unsigned
short
m
[
4
][
5
],
unsigned
short
*
coefs
,
int
*
row_order
)
{
unsigned
short
tmp
[
4
];
tmp
[
0
]
=
gf4096_mul
(
m
[
3
][
4
],
gf4096_inv
(
m
[
3
][
0
]));
tmp
[
1
]
=
gf4096_mul
((
gf4096_mul
(
tmp
[
0
],
m
[
2
][
0
])
^
m
[
2
][
4
]),
gf4096_inv
(
m
[
2
][
1
]));
tmp
[
2
]
=
gf4096_mul
((
gf4096_mul
(
tmp
[
0
],
m
[
1
][
0
])
^
gf4096_mul
(
tmp
[
1
],
m
[
1
][
1
])
^
m
[
1
][
4
]),
gf4096_inv
(
m
[
1
][
2
]));
tmp
[
3
]
=
gf4096_mul
((
gf4096_mul
(
tmp
[
0
],
m
[
0
][
0
])
^
gf4096_mul
(
tmp
[
1
],
m
[
0
][
1
])
^
gf4096_mul
(
tmp
[
2
],
m
[
0
][
2
])
^
m
[
0
][
4
]),
gf4096_inv
(
m
[
0
][
3
]));
sort_coefs
(
row_order
,
tmp
,
4
);
coefs
[
0
]
=
tmp
[
0
];
coefs
[
1
]
=
tmp
[
1
];
coefs
[
2
]
=
tmp
[
2
];
coefs
[
3
]
=
tmp
[
3
];
}
static
void
sort_coefs
(
int
*
order
,
unsigned
short
*
soln
,
int
len
)
{
int
cnt
,
start_cnt
,
least_ord
,
least_cnt
;
unsigned
short
tmp0
;
for
(
start_cnt
=
0
;
start_cnt
<
len
;
start_cnt
++
)
{
for
(
cnt
=
start_cnt
;
cnt
<
len
;
cnt
++
)
{
if
(
cnt
==
start_cnt
)
{
least_ord
=
order
[
cnt
];
least_cnt
=
start_cnt
;
}
else
{
if
(
least_ord
>
order
[
cnt
])
{
least_ord
=
order
[
cnt
];
least_cnt
=
cnt
;
}
}
}
if
(
least_cnt
!=
start_cnt
)
{
tmp0
=
order
[
least_cnt
];
order
[
least_cnt
]
=
order
[
start_cnt
];
order
[
start_cnt
]
=
tmp0
;
tmp0
=
soln
[
least_cnt
];
soln
[
least_cnt
]
=
soln
[
start_cnt
];
soln
[
start_cnt
]
=
tmp0
;
}
}
}
static
void
find_4bit_err_pats
(
unsigned
short
s0
,
unsigned
short
s1
,
unsigned
short
s2
,
unsigned
short
s3
,
unsigned
short
z1
,
unsigned
short
z2
,
unsigned
short
z3
,
unsigned
short
z4
,
unsigned
short
*
pats
)
{
unsigned
short
z4_z1
,
z3z4_z3z3
,
z4_z2
,
s0z4_s1
,
z1z4_z1z1
,
z4_z3
,
z2z4_z2z2
,
s1z4_s2
,
z3z3z4_z3z3z3
,
z1z1z4_z1z1z1
,
z2z2z4_z2z2z2
,
s2z4_s3
;
unsigned
short
tmp0
,
tmp1
,
tmp2
,
tmp3
;
z4_z1
=
z4
^
z1
;
z3z4_z3z3
=
gf4096_mul
(
z3
,
z4
)
^
gf4096_mul
(
z3
,
z3
);
z4_z2
=
z4
^
z2
;
s0z4_s1
=
gf4096_mul
(
s0
,
z4
)
^
s1
;
z1z4_z1z1
=
gf4096_mul
(
z1
,
z4
)
^
gf4096_mul
(
z1
,
z1
);
z4_z3
=
z4
^
z3
;
z2z4_z2z2
=
gf4096_mul
(
z2
,
z4
)
^
gf4096_mul
(
z2
,
z2
);
s1z4_s2
=
gf4096_mul
(
s1
,
z4
)
^
s2
;
z3z3z4_z3z3z3
=
gf4096_mul
(
gf4096_mul
(
z3
,
z3
),
z4
)
^
gf4096_mul
(
gf4096_mul
(
z3
,
z3
),
z3
);
z1z1z4_z1z1z1
=
gf4096_mul
(
gf4096_mul
(
z1
,
z1
),
z4
)
^
gf4096_mul
(
gf4096_mul
(
z1
,
z1
),
z1
);
z2z2z4_z2z2z2
=
gf4096_mul
(
gf4096_mul
(
z2
,
z2
),
z4
)
^
gf4096_mul
(
gf4096_mul
(
z2
,
z2
),
z2
);
s2z4_s3
=
gf4096_mul
(
s2
,
z4
)
^
s3
;
//find err pat 0,1
find_2x2_soln
(
gf4096_mul
(
z4_z1
,
z3z4_z3z3
)
^
gf4096_mul
(
z1z4_z1z1
,
z4_z3
),
gf4096_mul
(
z4_z2
,
z3z4_z3z3
)
^
gf4096_mul
(
z2z4_z2z2
,
z4_z3
),
gf4096_mul
(
z1z4_z1z1
,
z3z3z4_z3z3z3
)
^
gf4096_mul
(
z1z1z4_z1z1z1
,
z3z4_z3z3
),
gf4096_mul
(
z2z4_z2z2
,
z3z3z4_z3z3z3
)
^
gf4096_mul
(
z2z2z4_z2z2z2
,
z3z4_z3z3
),
gf4096_mul
(
s0z4_s1
,
z3z4_z3z3
)
^
gf4096_mul
(
s1z4_s2
,
z4_z3
),
gf4096_mul
(
s1z4_s2
,
z3z3z4_z3z3z3
)
^
gf4096_mul
(
s2z4_s3
,
z3z4_z3z3
),
pats
);
tmp0
=
pats
[
0
];
tmp1
=
pats
[
1
];
tmp2
=
pats
[
0
]
^
pats
[
1
]
^
s0
;
tmp3
=
gf4096_mul
(
pats
[
0
],
z1
)
^
gf4096_mul
(
pats
[
1
],
z2
)
^
s1
;
//find err pat 2,3
find_2x2_soln
(
0x1
,
0x1
,
z3
,
z4
,
tmp2
,
tmp3
,
pats
);
pats
[
2
]
=
pats
[
0
];
pats
[
3
]
=
pats
[
1
];
pats
[
0
]
=
tmp0
;
pats
[
1
]
=
tmp1
;
}
static
void
find_2x2_soln
(
unsigned
short
c00
,
unsigned
short
c01
,
unsigned
short
c10
,
unsigned
short
c11
,
unsigned
short
lval0
,
unsigned
short
lval1
,
unsigned
short
*
soln
)
{
unsigned
short
m
[
2
][
3
];
m
[
0
][
0
]
=
c00
;
m
[
0
][
1
]
=
c01
;
m
[
0
][
2
]
=
lval0
;
m
[
1
][
0
]
=
c10
;
m
[
1
][
1
]
=
c11
;
m
[
1
][
2
]
=
lval1
;
if
(
m
[
0
][
1
]
!=
0x0
)
{
/* */
}
else
if
(
m
[
1
][
1
]
!=
0x0
)
{
swap_2x3_rows
(
m
);
}
else
{
printk
(
KERN_ERR
"Warning: find_2bit_err_coefs, s0,s1 all zeros!
\n
"
);
}
solve_2x3
(
m
,
soln
);
}
static
void
swap_2x3_rows
(
unsigned
short
m
[
2
][
3
])
{
unsigned
short
tmp0
;
int
cnt
;
for
(
cnt
=
0
;
cnt
<
3
;
cnt
++
)
{
tmp0
=
m
[
0
][
cnt
];
m
[
0
][
cnt
]
=
m
[
1
][
cnt
];
m
[
1
][
cnt
]
=
tmp0
;
}
}
static
void
solve_2x3
(
unsigned
short
m
[
2
][
3
],
unsigned
short
*
coefs
)
{
unsigned
short
minv
;
minv
=
gf4096_mul
(
m
[
1
][
1
],
gf4096_inv
(
m
[
0
][
1
]));
m
[
1
][
0
]
=
m
[
1
][
0
]
^
gf4096_mul
(
m
[
0
][
0
],
minv
);
m
[
1
][
2
]
=
m
[
1
][
2
]
^
gf4096_mul
(
m
[
0
][
2
],
minv
);
coefs
[
0
]
=
gf4096_mul
(
m
[
1
][
2
],
gf4096_inv
(
m
[
1
][
0
]));
coefs
[
1
]
=
gf4096_mul
((
gf4096_mul
(
coefs
[
0
],
m
[
0
][
0
])
^
m
[
0
][
2
]),
gf4096_inv
(
m
[
0
][
1
]));
}
static
unsigned
char
gf64_inv
[
64
]
=
{
0
,
1
,
33
,
62
,
49
,
43
,
31
,
44
,
57
,
37
,
52
,
28
,
46
,
40
,
22
,
25
,
61
,
54
,
51
,
39
,
26
,
35
,
14
,
24
,
23
,
15
,
20
,
34
,
11
,
53
,
45
,
6
,
63
,
2
,
27
,
21
,
56
,
9
,
50
,
19
,
13
,
47
,
48
,
5
,
7
,
30
,
12
,
41
,
42
,
4
,
38
,
18
,
10
,
29
,
17
,
60
,
36
,
8
,
59
,
58
,
55
,
16
,
3
,
32
};
static
unsigned
short
gf4096_inv
(
unsigned
short
din
)
{
unsigned
short
alahxal
,
ah2B
,
deno
,
inv
,
bl
,
bh
;
unsigned
short
ah
,
al
,
ahxal
;
unsigned
short
dout
;
ah
=
(
din
>>
6
)
&
0x3f
;
al
=
din
&
0x3f
;
ahxal
=
ah
^
al
;
ah2B
=
(((
ah
^
(
ah
>>
3
))
&
0x1
)
<<
5
)
|
((
ah
>>
1
)
&
0x10
)
|
((((
ah
>>
5
)
^
(
ah
>>
2
))
&
0x1
)
<<
3
)
|
((
ah
>>
2
)
&
0x4
)
|
((((
ah
>>
4
)
^
(
ah
>>
1
))
&
0x1
)
<<
1
)
|
(
ah
&
0x1
);
alahxal
=
gf64_mul
(
ahxal
,
al
);
deno
=
alahxal
^
ah2B
;
inv
=
gf64_inv
[
deno
];
bl
=
gf64_mul
(
inv
,
ahxal
);
bh
=
gf64_mul
(
inv
,
ah
);
dout
=
((
bh
&
0x3f
)
<<
6
)
|
(
bl
&
0x3f
);
return
(((
bh
&
0x3f
)
<<
6
)
|
(
bl
&
0x3f
));
}
static
unsigned
short
err_pos_lut
[
4096
]
=
{
0xfff
,
0x000
,
0x451
,
0xfff
,
0xfff
,
0x3cf
,
0xfff
,
0x041
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x28a
,
0xfff
,
0x492
,
0xfff
,
0x145
,
0xfff
,
0xfff
,
0x514
,
0xfff
,
0x082
,
0xfff
,
0xfff
,
0xfff
,
0x249
,
0x38e
,
0x410
,
0xfff
,
0x104
,
0x208
,
0x1c7
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2cb
,
0xfff
,
0xfff
,
0xfff
,
0x0c3
,
0x34d
,
0x4d3
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x186
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x30c
,
0x555
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x166
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x385
,
0x14e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4e1
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x538
,
0xfff
,
0x16d
,
0xfff
,
0xfff
,
0xfff
,
0x45b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x29c
,
0x2cc
,
0x30b
,
0x2b3
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0b3
,
0xfff
,
0x2f7
,
0xfff
,
0x32b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0a7
,
0xfff
,
0xfff
,
0x2da
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x07e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x11c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x22f
,
0xfff
,
0x1f4
,
0xfff
,
0xfff
,
0x2b0
,
0x504
,
0xfff
,
0x114
,
0xfff
,
0xfff
,
0xfff
,
0x21d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x00d
,
0x3c4
,
0x340
,
0x10f
,
0xfff
,
0xfff
,
0x266
,
0x02e
,
0xfff
,
0xfff
,
0xfff
,
0x4f8
,
0x337
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x07b
,
0x168
,
0xfff
,
0xfff
,
0x0fe
,
0xfff
,
0xfff
,
0x51a
,
0xfff
,
0x458
,
0xfff
,
0x36d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x073
,
0x37d
,
0x415
,
0x550
,
0xfff
,
0xfff
,
0xfff
,
0x23b
,
0x4b4
,
0xfff
,
0xfff
,
0xfff
,
0x1a1
,
0xfff
,
0xfff
,
0x3aa
,
0xfff
,
0x117
,
0x04d
,
0x341
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x518
,
0x03e
,
0x0f2
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x363
,
0xfff
,
0x0b9
,
0xfff
,
0xfff
,
0x241
,
0xfff
,
0xfff
,
0x049
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x15f
,
0x52d
,
0xfff
,
0xfff
,
0xfff
,
0x29e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4cf
,
0x0fc
,
0xfff
,
0x36f
,
0x3d3
,
0xfff
,
0x228
,
0xfff
,
0xfff
,
0x45e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x238
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x47f
,
0xfff
,
0xfff
,
0x43a
,
0x265
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3e8
,
0xfff
,
0xfff
,
0x01a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x21e
,
0x1fc
,
0x40b
,
0xfff
,
0xfff
,
0xfff
,
0x2d0
,
0x159
,
0xfff
,
0xfff
,
0x313
,
0xfff
,
0xfff
,
0x05c
,
0x4cc
,
0xfff
,
0xfff
,
0x0f6
,
0x3d5
,
0xfff
,
0xfff
,
0xfff
,
0x54f
,
0xfff
,
0xfff
,
0xfff
,
0x172
,
0x1e4
,
0x07c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x53c
,
0x1ad
,
0x535
,
0x19b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x092
,
0xfff
,
0x2be
,
0xfff
,
0xfff
,
0x482
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0e6
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x476
,
0xfff
,
0x51d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x342
,
0x2b5
,
0x22e
,
0x09a
,
0xfff
,
0x08d
,
0x44f
,
0x3ed
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3d1
,
0xfff
,
0xfff
,
0x543
,
0xfff
,
0x48f
,
0xfff
,
0x3d2
,
0xfff
,
0x0d5
,
0x113
,
0x0ec
,
0x427
,
0xfff
,
0xfff
,
0xfff
,
0x4c4
,
0xfff
,
0xfff
,
0x50a
,
0xfff
,
0x144
,
0xfff
,
0x105
,
0x39f
,
0x294
,
0x164
,
0xfff
,
0x31a
,
0xfff
,
0xfff
,
0x49a
,
0xfff
,
0x130
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1be
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x49e
,
0x371
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0e8
,
0x49c
,
0x0f4
,
0xfff
,
0x338
,
0x1a7
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x36c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1ae
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x31b
,
0xfff
,
0xfff
,
0x2dd
,
0x522
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2f4
,
0x3c6
,
0x30d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x34c
,
0x18f
,
0x30a
,
0xfff
,
0x01f
,
0x079
,
0xfff
,
0xfff
,
0x54d
,
0x46b
,
0x28c
,
0x37f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x355
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x14f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x359
,
0x3fe
,
0x3c5
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x423
,
0xfff
,
0xfff
,
0x34a
,
0x22c
,
0xfff
,
0x25a
,
0xfff
,
0xfff
,
0x4ad
,
0xfff
,
0x28d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x547
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2e2
,
0xfff
,
0xfff
,
0x1d5
,
0xfff
,
0x2a8
,
0xfff
,
0xfff
,
0x03f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3eb
,
0x0fa
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x55b
,
0xfff
,
0x08e
,
0xfff
,
0x3ae
,
0xfff
,
0x3a4
,
0xfff
,
0x282
,
0x158
,
0xfff
,
0x382
,
0xfff
,
0xfff
,
0x499
,
0xfff
,
0xfff
,
0x08a
,
0xfff
,
0xfff
,
0xfff
,
0x456
,
0x3be
,
0xfff
,
0x1e2
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x559
,
0xfff
,
0x1a0
,
0xfff
,
0xfff
,
0x0b4
,
0xfff
,
0xfff
,
0xfff
,
0x2df
,
0xfff
,
0xfff
,
0xfff
,
0x07f
,
0x4f5
,
0xfff
,
0xfff
,
0x27c
,
0x133
,
0x017
,
0xfff
,
0x3fd
,
0xfff
,
0xfff
,
0xfff
,
0x44d
,
0x4cd
,
0x17a
,
0x0d7
,
0x537
,
0xfff
,
0xfff
,
0x353
,
0xfff
,
0xfff
,
0x351
,
0x366
,
0xfff
,
0x44a
,
0xfff
,
0x1a6
,
0xfff
,
0xfff
,
0xfff
,
0x291
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1e3
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x389
,
0xfff
,
0x07a
,
0xfff
,
0x1b6
,
0x2ed
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x24e
,
0x074
,
0xfff
,
0xfff
,
0x3dc
,
0xfff
,
0x4e3
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4eb
,
0xfff
,
0xfff
,
0x3b8
,
0x4de
,
0xfff
,
0x19c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x262
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x076
,
0x4e8
,
0x3da
,
0xfff
,
0x531
,
0xfff
,
0xfff
,
0x14a
,
0xfff
,
0x0a2
,
0x433
,
0x3df
,
0x1e9
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3e7
,
0x285
,
0x2d8
,
0xfff
,
0xfff
,
0xfff
,
0x349
,
0x18d
,
0x098
,
0xfff
,
0x0df
,
0x4bf
,
0xfff
,
0xfff
,
0x0b2
,
0xfff
,
0x346
,
0x24d
,
0xfff
,
0xfff
,
0xfff
,
0x24f
,
0x4fa
,
0x2f9
,
0xfff
,
0xfff
,
0x3c9
,
0xfff
,
0x2b4
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x056
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x179
,
0xfff
,
0x0e9
,
0x3f0
,
0x33d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1fd
,
0xfff
,
0xfff
,
0x526
,
0xfff
,
0xfff
,
0xfff
,
0x53d
,
0xfff
,
0xfff
,
0xfff
,
0x170
,
0x331
,
0xfff
,
0x068
,
0xfff
,
0xfff
,
0xfff
,
0x3f7
,
0xfff
,
0x3d8
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x09f
,
0x556
,
0xfff
,
0xfff
,
0x02d
,
0xfff
,
0xfff
,
0x553
,
0xfff
,
0xfff
,
0xfff
,
0x1f0
,
0xfff
,
0xfff
,
0x4d6
,
0x41e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4d5
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x248
,
0xfff
,
0xfff
,
0xfff
,
0x0a3
,
0xfff
,
0x217
,
0xfff
,
0xfff
,
0xfff
,
0x4f1
,
0x209
,
0xfff
,
0xfff
,
0x475
,
0x234
,
0x52b
,
0x398
,
0xfff
,
0x08b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2c2
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x268
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4a3
,
0xfff
,
0x0aa
,
0xfff
,
0x1d9
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x155
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0bf
,
0x539
,
0xfff
,
0xfff
,
0x2f1
,
0x545
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2a7
,
0x06f
,
0xfff
,
0x378
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x25e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x15d
,
0x02a
,
0xfff
,
0xfff
,
0x0bc
,
0x235
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x150
,
0xfff
,
0x1a9
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x381
,
0xfff
,
0x04e
,
0x270
,
0x13f
,
0xfff
,
0xfff
,
0x405
,
0xfff
,
0x3cd
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2ef
,
0xfff
,
0x06a
,
0xfff
,
0xfff
,
0xfff
,
0x34f
,
0x212
,
0xfff
,
0xfff
,
0x0e2
,
0xfff
,
0x083
,
0x298
,
0xfff
,
0xfff
,
0xfff
,
0x0c2
,
0xfff
,
0xfff
,
0x52e
,
0xfff
,
0x488
,
0xfff
,
0xfff
,
0xfff
,
0x36b
,
0xfff
,
0xfff
,
0xfff
,
0x442
,
0x091
,
0xfff
,
0x41c
,
0xfff
,
0xfff
,
0x3a5
,
0xfff
,
0x4e6
,
0xfff
,
0xfff
,
0x40d
,
0x31d
,
0xfff
,
0xfff
,
0xfff
,
0x4c1
,
0x053
,
0xfff
,
0x418
,
0x13c
,
0xfff
,
0x350
,
0xfff
,
0x0ae
,
0xfff
,
0xfff
,
0x41f
,
0xfff
,
0x470
,
0xfff
,
0x4ca
,
0xfff
,
0xfff
,
0xfff
,
0x02b
,
0x450
,
0xfff
,
0x1f8
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x293
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x411
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0b8
,
0xfff
,
0xfff
,
0xfff
,
0x3e1
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x43c
,
0xfff
,
0x2b2
,
0x2ab
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1ec
,
0xfff
,
0xfff
,
0xfff
,
0x3f8
,
0x034
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x11a
,
0xfff
,
0x541
,
0x45c
,
0x134
,
0x1cc
,
0xfff
,
0xfff
,
0xfff
,
0x469
,
0xfff
,
0xfff
,
0x44b
,
0x161
,
0xfff
,
0xfff
,
0xfff
,
0x055
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x307
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2d1
,
0xfff
,
0xfff
,
0xfff
,
0x124
,
0x37b
,
0x26b
,
0x336
,
0xfff
,
0xfff
,
0x2e4
,
0x3cb
,
0xfff
,
0xfff
,
0x0f8
,
0x3c8
,
0xfff
,
0xfff
,
0xfff
,
0x461
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4b5
,
0x2cf
,
0xfff
,
0xfff
,
0xfff
,
0x20f
,
0xfff
,
0x35a
,
0xfff
,
0x490
,
0xfff
,
0x185
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x42e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x54b
,
0xfff
,
0xfff
,
0xfff
,
0x146
,
0xfff
,
0x412
,
0xfff
,
0xfff
,
0xfff
,
0x1ff
,
0xfff
,
0xfff
,
0x3e0
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2d5
,
0xfff
,
0x4df
,
0x505
,
0xfff
,
0x413
,
0xfff
,
0x1a5
,
0xfff
,
0x3b2
,
0xfff
,
0xfff
,
0xfff
,
0x35b
,
0xfff
,
0x116
,
0xfff
,
0xfff
,
0x171
,
0x4d0
,
0xfff
,
0x154
,
0x12d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x468
,
0x4db
,
0xfff
,
0xfff
,
0x1df
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x05a
,
0xfff
,
0x0f1
,
0x403
,
0xfff
,
0x22b
,
0x2e0
,
0xfff
,
0xfff
,
0xfff
,
0x2b7
,
0x373
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x13e
,
0xfff
,
0xfff
,
0xfff
,
0x0d0
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x329
,
0x1d2
,
0x3fa
,
0x047
,
0xfff
,
0x2f2
,
0xfff
,
0xfff
,
0x141
,
0x0ac
,
0x1d7
,
0xfff
,
0x07d
,
0xfff
,
0xfff
,
0xfff
,
0x1c1
,
0xfff
,
0x487
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x045
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x288
,
0x0cd
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x226
,
0x1d8
,
0xfff
,
0x153
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4cb
,
0x528
,
0xfff
,
0xfff
,
0xfff
,
0x20a
,
0x343
,
0x3a1
,
0xfff
,
0xfff
,
0xfff
,
0x2d7
,
0x2d3
,
0x1aa
,
0x4c5
,
0xfff
,
0xfff
,
0xfff
,
0x42b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3e9
,
0xfff
,
0x20b
,
0x260
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x37c
,
0x2fd
,
0xfff
,
0xfff
,
0x2c8
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x31e
,
0xfff
,
0x335
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x135
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x35c
,
0x4dd
,
0x129
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1ef
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x34e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x407
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3ad
,
0xfff
,
0xfff
,
0xfff
,
0x379
,
0xfff
,
0xfff
,
0x1d0
,
0x38d
,
0xfff
,
0xfff
,
0x1e8
,
0x184
,
0x3c1
,
0x1c4
,
0xfff
,
0x1f9
,
0xfff
,
0xfff
,
0x424
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1d3
,
0x0d4
,
0xfff
,
0x4e9
,
0xfff
,
0xfff
,
0xfff
,
0x530
,
0x107
,
0xfff
,
0x106
,
0x04f
,
0xfff
,
0xfff
,
0x4c7
,
0x503
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x15c
,
0xfff
,
0x23f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4f3
,
0xfff
,
0xfff
,
0x3c7
,
0xfff
,
0x278
,
0xfff
,
0xfff
,
0x0a6
,
0xfff
,
0xfff
,
0xfff
,
0x122
,
0x1cf
,
0xfff
,
0x327
,
0xfff
,
0x2e5
,
0xfff
,
0x29d
,
0xfff
,
0xfff
,
0x3f1
,
0xfff
,
0xfff
,
0x48d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x054
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x178
,
0x27e
,
0x4e0
,
0x352
,
0x02f
,
0x09c
,
0xfff
,
0x2a0
,
0xfff
,
0xfff
,
0x46a
,
0x457
,
0xfff
,
0xfff
,
0x501
,
0xfff
,
0x2ba
,
0xfff
,
0xfff
,
0xfff
,
0x54e
,
0x2e7
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x551
,
0xfff
,
0xfff
,
0x1db
,
0x2aa
,
0xfff
,
0xfff
,
0x4bc
,
0xfff
,
0xfff
,
0x395
,
0xfff
,
0x0de
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x455
,
0xfff
,
0x17e
,
0xfff
,
0x221
,
0x4a7
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x388
,
0xfff
,
0xfff
,
0xfff
,
0x308
,
0xfff
,
0xfff
,
0xfff
,
0x20e
,
0x4b9
,
0xfff
,
0x273
,
0x20c
,
0x09e
,
0xfff
,
0x057
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3f2
,
0xfff
,
0x1a8
,
0x3a6
,
0x14c
,
0xfff
,
0xfff
,
0x071
,
0xfff
,
0xfff
,
0x53a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x109
,
0xfff
,
0xfff
,
0x399
,
0xfff
,
0x061
,
0x4f0
,
0x39e
,
0x244
,
0xfff
,
0x035
,
0xfff
,
0xfff
,
0x305
,
0x47e
,
0x297
,
0xfff
,
0xfff
,
0x2b8
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1bc
,
0xfff
,
0x2fc
,
0xfff
,
0xfff
,
0x554
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3b6
,
0xfff
,
0xfff
,
0xfff
,
0x515
,
0x397
,
0xfff
,
0xfff
,
0x12f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4e5
,
0xfff
,
0x4fc
,
0xfff
,
0xfff
,
0x05e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0a8
,
0x3af
,
0x015
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x138
,
0xfff
,
0xfff
,
0xfff
,
0x540
,
0xfff
,
0xfff
,
0xfff
,
0x027
,
0x523
,
0x2f0
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x16c
,
0xfff
,
0x27d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x04c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4dc
,
0xfff
,
0xfff
,
0x059
,
0x301
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1a3
,
0xfff
,
0x15a
,
0xfff
,
0xfff
,
0x0a5
,
0xfff
,
0x435
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x051
,
0xfff
,
0xfff
,
0x131
,
0xfff
,
0x4f4
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x441
,
0xfff
,
0x4fb
,
0xfff
,
0x03b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1ed
,
0x274
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0d3
,
0x55e
,
0x1b3
,
0xfff
,
0x0bd
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x225
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4b7
,
0xfff
,
0xfff
,
0x2ff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4c3
,
0xfff
,
0x383
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2f6
,
0xfff
,
0xfff
,
0x1ee
,
0xfff
,
0x03d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x26f
,
0x1dc
,
0xfff
,
0x0db
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0ce
,
0xfff
,
0xfff
,
0x127
,
0x03a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x311
,
0xfff
,
0xfff
,
0x13d
,
0x09d
,
0x47b
,
0x2a6
,
0x50d
,
0x510
,
0x19a
,
0xfff
,
0x354
,
0x414
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x44c
,
0x3b0
,
0xfff
,
0x23d
,
0x429
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4c0
,
0x416
,
0xfff
,
0x05b
,
0xfff
,
0xfff
,
0x137
,
0xfff
,
0x25f
,
0x49f
,
0xfff
,
0x279
,
0x013
,
0xfff
,
0xfff
,
0xfff
,
0x269
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3d0
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x077
,
0xfff
,
0xfff
,
0x3fb
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x271
,
0x3a0
,
0xfff
,
0xfff
,
0x40f
,
0xfff
,
0xfff
,
0x3de
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1ab
,
0x26a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x489
,
0xfff
,
0xfff
,
0x252
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1b7
,
0x42f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3b7
,
0xfff
,
0x2bb
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0f7
,
0x01d
,
0xfff
,
0x067
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4e2
,
0xfff
,
0xfff
,
0x4bb
,
0xfff
,
0xfff
,
0xfff
,
0x17b
,
0xfff
,
0x0ee
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x36e
,
0xfff
,
0xfff
,
0xfff
,
0x533
,
0xfff
,
0xfff
,
0xfff
,
0x4d4
,
0x356
,
0xfff
,
0xfff
,
0x375
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4a4
,
0x513
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4ff
,
0xfff
,
0x2af
,
0xfff
,
0xfff
,
0x026
,
0xfff
,
0x0ad
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x26e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x493
,
0xfff
,
0x463
,
0x4d2
,
0x4be
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4f2
,
0x0b6
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x32d
,
0x315
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x13a
,
0x4a1
,
0xfff
,
0x27a
,
0xfff
,
0xfff
,
0xfff
,
0x47a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x334
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x54c
,
0xfff
,
0xfff
,
0xfff
,
0x0c9
,
0x007
,
0xfff
,
0xfff
,
0x12e
,
0xfff
,
0x0ff
,
0xfff
,
0xfff
,
0x3f5
,
0x509
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1c3
,
0x2ad
,
0xfff
,
0xfff
,
0x47c
,
0x261
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x152
,
0xfff
,
0xfff
,
0xfff
,
0x339
,
0xfff
,
0x243
,
0x1c0
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x063
,
0xfff
,
0xfff
,
0x254
,
0xfff
,
0xfff
,
0x173
,
0xfff
,
0x0c7
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x362
,
0x259
,
0x485
,
0x374
,
0x0dc
,
0x3ab
,
0xfff
,
0x1c5
,
0x534
,
0x544
,
0xfff
,
0xfff
,
0x508
,
0xfff
,
0x402
,
0x408
,
0xfff
,
0x0e7
,
0xfff
,
0xfff
,
0x00a
,
0x205
,
0xfff
,
0xfff
,
0x2b9
,
0xfff
,
0xfff
,
0xfff
,
0x465
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x23a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x147
,
0x19d
,
0x115
,
0x214
,
0xfff
,
0x090
,
0x368
,
0xfff
,
0x210
,
0xfff
,
0xfff
,
0x280
,
0x52a
,
0x163
,
0x148
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x326
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2de
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x206
,
0x2c1
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x189
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x367
,
0xfff
,
0x1a4
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x443
,
0xfff
,
0x27b
,
0xfff
,
0xfff
,
0x251
,
0x549
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x188
,
0x04b
,
0xfff
,
0xfff
,
0xfff
,
0x31f
,
0x4a6
,
0xfff
,
0x246
,
0x1de
,
0x156
,
0xfff
,
0xfff
,
0xfff
,
0x3a9
,
0xfff
,
0xfff
,
0xfff
,
0x2fa
,
0xfff
,
0x128
,
0x0d1
,
0x449
,
0x255
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x258
,
0xfff
,
0xfff
,
0xfff
,
0x532
,
0xfff
,
0xfff
,
0xfff
,
0x303
,
0x517
,
0xfff
,
0xfff
,
0x2a9
,
0x24a
,
0xfff
,
0xfff
,
0x231
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4b6
,
0x516
,
0xfff
,
0xfff
,
0x0e4
,
0x0eb
,
0xfff
,
0x4e4
,
0xfff
,
0x275
,
0xfff
,
0xfff
,
0x031
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x025
,
0x21a
,
0xfff
,
0x0cc
,
0x45f
,
0x3d9
,
0x289
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x23e
,
0xfff
,
0xfff
,
0xfff
,
0x438
,
0x097
,
0x419
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0a9
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x37e
,
0x0e0
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x431
,
0x372
,
0xfff
,
0xfff
,
0xfff
,
0x1ba
,
0x06e
,
0xfff
,
0x1b1
,
0xfff
,
0xfff
,
0x12a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x193
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x10a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x048
,
0x1b4
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x295
,
0x140
,
0x108
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x16f
,
0xfff
,
0x0a4
,
0x37a
,
0xfff
,
0x29a
,
0xfff
,
0x284
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4c6
,
0x2a2
,
0x3a3
,
0xfff
,
0x201
,
0xfff
,
0xfff
,
0xfff
,
0x4bd
,
0x005
,
0x54a
,
0x3b5
,
0x204
,
0x2ee
,
0x11d
,
0x436
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3ec
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x11f
,
0x498
,
0x21c
,
0xfff
,
0xfff
,
0xfff
,
0x3d6
,
0xfff
,
0x4ab
,
0xfff
,
0x432
,
0x2eb
,
0x542
,
0x4fd
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4ce
,
0xfff
,
0xfff
,
0x2fb
,
0xfff
,
0xfff
,
0x2e1
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1b9
,
0x037
,
0x0dd
,
0xfff
,
0xfff
,
0xfff
,
0x2bf
,
0x521
,
0x496
,
0x095
,
0xfff
,
0xfff
,
0x328
,
0x070
,
0x1bf
,
0xfff
,
0x393
,
0xfff
,
0xfff
,
0x102
,
0xfff
,
0xfff
,
0x21b
,
0xfff
,
0x142
,
0x263
,
0x519
,
0xfff
,
0x2a5
,
0x177
,
0xfff
,
0x14d
,
0x471
,
0x4ae
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1f6
,
0xfff
,
0x481
,
0xfff
,
0xfff
,
0xfff
,
0x151
,
0xfff
,
0xfff
,
0xfff
,
0x085
,
0x33f
,
0xfff
,
0xfff
,
0xfff
,
0x084
,
0xfff
,
0xfff
,
0xfff
,
0x345
,
0x3a2
,
0xfff
,
0xfff
,
0x0a0
,
0x0da
,
0x024
,
0xfff
,
0xfff
,
0xfff
,
0x1bd
,
0xfff
,
0x55c
,
0x467
,
0x445
,
0xfff
,
0xfff
,
0xfff
,
0x052
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x51e
,
0xfff
,
0xfff
,
0x39d
,
0xfff
,
0x35f
,
0xfff
,
0x376
,
0x3ee
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x448
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x16a
,
0xfff
,
0x036
,
0x38f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x211
,
0xfff
,
0xfff
,
0xfff
,
0x230
,
0xfff
,
0xfff
,
0x3ba
,
0xfff
,
0xfff
,
0xfff
,
0x3ce
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x229
,
0xfff
,
0x176
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x00b
,
0xfff
,
0x162
,
0x018
,
0xfff
,
0xfff
,
0x233
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x400
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x12b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3f4
,
0xfff
,
0x0f0
,
0xfff
,
0x1ac
,
0xfff
,
0xfff
,
0x119
,
0xfff
,
0x2c0
,
0xfff
,
0xfff
,
0xfff
,
0x49b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x23c
,
0xfff
,
0x4b3
,
0x010
,
0x064
,
0xfff
,
0xfff
,
0x4ba
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3c2
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x006
,
0x196
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x100
,
0x191
,
0xfff
,
0x1ea
,
0x29f
,
0xfff
,
0xfff
,
0xfff
,
0x276
,
0xfff
,
0xfff
,
0x2b1
,
0x3b9
,
0xfff
,
0x03c
,
0xfff
,
0xfff
,
0xfff
,
0x180
,
0xfff
,
0x08f
,
0xfff
,
0xfff
,
0x19e
,
0x019
,
0xfff
,
0x0b0
,
0x0fd
,
0x332
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x06b
,
0x2e8
,
0xfff
,
0x446
,
0xfff
,
0xfff
,
0x004
,
0x247
,
0x197
,
0xfff
,
0x112
,
0x169
,
0x292
,
0xfff
,
0x302
,
0xfff
,
0xfff
,
0x33b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x287
,
0x21f
,
0xfff
,
0x3ea
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4e7
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3a8
,
0xfff
,
0xfff
,
0x2bc
,
0xfff
,
0x484
,
0x296
,
0xfff
,
0x1c9
,
0x08c
,
0x1e5
,
0x48a
,
0xfff
,
0x360
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1ca
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x10d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x066
,
0x2ea
,
0x28b
,
0x25b
,
0xfff
,
0x072
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2b6
,
0xfff
,
0xfff
,
0x272
,
0xfff
,
0xfff
,
0x525
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2ca
,
0xfff
,
0xfff
,
0xfff
,
0x299
,
0xfff
,
0xfff
,
0xfff
,
0x558
,
0x41a
,
0xfff
,
0x4f7
,
0x557
,
0xfff
,
0x4a0
,
0x344
,
0x12c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x125
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x40e
,
0xfff
,
0xfff
,
0x502
,
0xfff
,
0x103
,
0x3e6
,
0xfff
,
0x527
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x45d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x44e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0d2
,
0x4c9
,
0x35e
,
0x459
,
0x2d9
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x17d
,
0x0c4
,
0xfff
,
0xfff
,
0xfff
,
0x3ac
,
0x390
,
0x094
,
0xfff
,
0x483
,
0x0ab
,
0xfff
,
0x253
,
0xfff
,
0x391
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x123
,
0x0ef
,
0xfff
,
0xfff
,
0xfff
,
0x330
,
0x38c
,
0xfff
,
0xfff
,
0x2ae
,
0xfff
,
0xfff
,
0xfff
,
0x042
,
0x012
,
0x06d
,
0xfff
,
0xfff
,
0xfff
,
0x32a
,
0x3db
,
0x364
,
0x2dc
,
0xfff
,
0x30f
,
0x3d7
,
0x4a5
,
0x050
,
0xfff
,
0xfff
,
0x029
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1d1
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x480
,
0xfff
,
0x4ed
,
0x081
,
0x0a1
,
0xfff
,
0xfff
,
0xfff
,
0x30e
,
0x52f
,
0x257
,
0xfff
,
0xfff
,
0x447
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x401
,
0x3cc
,
0xfff
,
0xfff
,
0x0fb
,
0x2c9
,
0x42a
,
0x314
,
0x33e
,
0x3bd
,
0x318
,
0xfff
,
0x10e
,
0x2a1
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x24c
,
0x506
,
0xfff
,
0x267
,
0xfff
,
0xfff
,
0x219
,
0xfff
,
0x1eb
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x309
,
0x3e2
,
0x46c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x384
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x50c
,
0xfff
,
0x24b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x038
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x194
,
0x143
,
0x3e3
,
0xfff
,
0xfff
,
0xfff
,
0x4c2
,
0xfff
,
0xfff
,
0x0e1
,
0x25c
,
0xfff
,
0x237
,
0xfff
,
0x1fe
,
0xfff
,
0xfff
,
0xfff
,
0x065
,
0x2a4
,
0xfff
,
0x386
,
0x55a
,
0x11b
,
0xfff
,
0xfff
,
0x192
,
0xfff
,
0x183
,
0x00e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4b2
,
0x18e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x486
,
0x4ef
,
0x0c6
,
0x380
,
0xfff
,
0x4a8
,
0xfff
,
0x0c5
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x093
,
0x1b8
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2e6
,
0xfff
,
0x0f3
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x28e
,
0xfff
,
0x53b
,
0x420
,
0x22a
,
0x33a
,
0xfff
,
0x387
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2a3
,
0xfff
,
0xfff
,
0xfff
,
0x428
,
0x500
,
0xfff
,
0xfff
,
0x120
,
0x2c6
,
0x290
,
0x2f5
,
0x0e3
,
0xfff
,
0x0b7
,
0xfff
,
0x319
,
0x474
,
0xfff
,
0xfff
,
0xfff
,
0x529
,
0x014
,
0xfff
,
0x41b
,
0x40a
,
0x18b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0d9
,
0xfff
,
0x38a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1ce
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3b1
,
0xfff
,
0xfff
,
0x05d
,
0x2c4
,
0xfff
,
0xfff
,
0x4af
,
0xfff
,
0x030
,
0xfff
,
0xfff
,
0x203
,
0xfff
,
0x277
,
0x256
,
0xfff
,
0xfff
,
0xfff
,
0x4f9
,
0xfff
,
0x2c7
,
0xfff
,
0x466
,
0x016
,
0x1cd
,
0xfff
,
0x167
,
0xfff
,
0xfff
,
0x0c8
,
0xfff
,
0x43d
,
0xfff
,
0xfff
,
0x020
,
0xfff
,
0xfff
,
0x232
,
0x1cb
,
0x1e0
,
0xfff
,
0xfff
,
0x347
,
0xfff
,
0x478
,
0xfff
,
0x365
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x358
,
0xfff
,
0x10b
,
0xfff
,
0x35d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x452
,
0x22d
,
0xfff
,
0xfff
,
0x47d
,
0xfff
,
0x2f3
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x460
,
0xfff
,
0xfff
,
0xfff
,
0x50b
,
0xfff
,
0xfff
,
0xfff
,
0x2ec
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4b1
,
0x422
,
0xfff
,
0xfff
,
0xfff
,
0x2d4
,
0xfff
,
0x239
,
0xfff
,
0xfff
,
0xfff
,
0x439
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x491
,
0x075
,
0xfff
,
0xfff
,
0xfff
,
0x06c
,
0xfff
,
0xfff
,
0x0f9
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x139
,
0xfff
,
0x4f6
,
0xfff
,
0xfff
,
0x409
,
0xfff
,
0xfff
,
0x15b
,
0xfff
,
0xfff
,
0x348
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4a2
,
0x49d
,
0xfff
,
0x033
,
0x175
,
0xfff
,
0x039
,
0xfff
,
0x312
,
0x40c
,
0xfff
,
0xfff
,
0x325
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4aa
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x165
,
0x3bc
,
0x48c
,
0x310
,
0x096
,
0xfff
,
0xfff
,
0x250
,
0x1a2
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x20d
,
0x2ac
,
0xfff
,
0xfff
,
0x39b
,
0xfff
,
0x377
,
0xfff
,
0x512
,
0x495
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x357
,
0x4ea
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x198
,
0xfff
,
0xfff
,
0xfff
,
0x434
,
0x04a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x062
,
0xfff
,
0x1d6
,
0x1c8
,
0xfff
,
0x1f3
,
0x281
,
0xfff
,
0x462
,
0xfff
,
0xfff
,
0xfff
,
0x4b0
,
0xfff
,
0x207
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3dd
,
0xfff
,
0xfff
,
0x55d
,
0xfff
,
0x552
,
0x494
,
0x1af
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x227
,
0xfff
,
0xfff
,
0x069
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x43e
,
0x0b5
,
0xfff
,
0x524
,
0x2d2
,
0xfff
,
0xfff
,
0xfff
,
0x28f
,
0xfff
,
0x01b
,
0x50e
,
0xfff
,
0xfff
,
0x1bb
,
0xfff
,
0xfff
,
0x41d
,
0xfff
,
0x32e
,
0x48e
,
0xfff
,
0x1f7
,
0x224
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x394
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x52c
,
0xfff
,
0xfff
,
0xfff
,
0x392
,
0xfff
,
0x1e7
,
0xfff
,
0xfff
,
0x3f9
,
0x3a7
,
0xfff
,
0x51f
,
0xfff
,
0x0bb
,
0x118
,
0x3ca
,
0xfff
,
0x1dd
,
0xfff
,
0x48b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x50f
,
0xfff
,
0x0d6
,
0xfff
,
0x1fa
,
0xfff
,
0x11e
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x4d7
,
0xfff
,
0x078
,
0x008
,
0xfff
,
0x25d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x032
,
0x33c
,
0xfff
,
0x4d9
,
0x160
,
0xfff
,
0xfff
,
0x300
,
0x0b1
,
0xfff
,
0x322
,
0xfff
,
0x4ec
,
0xfff
,
0xfff
,
0x200
,
0x00c
,
0x369
,
0x473
,
0xfff
,
0xfff
,
0x32c
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x53e
,
0x3d4
,
0x417
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x34b
,
0x001
,
0x39a
,
0x02c
,
0xfff
,
0xfff
,
0x2ce
,
0x00f
,
0xfff
,
0x0ba
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x060
,
0xfff
,
0x406
,
0xfff
,
0xfff
,
0xfff
,
0x4ee
,
0x4ac
,
0xfff
,
0x43f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x29b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x216
,
0x190
,
0xfff
,
0x396
,
0x464
,
0xfff
,
0xfff
,
0x323
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2e9
,
0xfff
,
0x26d
,
0x2cd
,
0x040
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x38b
,
0x3c0
,
0xfff
,
0xfff
,
0xfff
,
0x1f2
,
0xfff
,
0x0ea
,
0xfff
,
0xfff
,
0x472
,
0xfff
,
0x1fb
,
0xfff
,
0xfff
,
0x0af
,
0x27f
,
0xfff
,
0xfff
,
0xfff
,
0x479
,
0x023
,
0xfff
,
0x0d8
,
0x3b3
,
0xfff
,
0xfff
,
0xfff
,
0x121
,
0xfff
,
0xfff
,
0x3bf
,
0xfff
,
0xfff
,
0x16b
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x45a
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x0be
,
0xfff
,
0xfff
,
0xfff
,
0x111
,
0xfff
,
0x220
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x09b
,
0x218
,
0xfff
,
0x022
,
0x202
,
0xfff
,
0x4c8
,
0xfff
,
0x0ed
,
0xfff
,
0xfff
,
0x182
,
0xfff
,
0xfff
,
0xfff
,
0x17f
,
0x213
,
0xfff
,
0x321
,
0x36a
,
0xfff
,
0x086
,
0xfff
,
0xfff
,
0xfff
,
0x43b
,
0x088
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x26c
,
0xfff
,
0x2f8
,
0x3b4
,
0xfff
,
0xfff
,
0xfff
,
0x132
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x333
,
0x444
,
0x0c1
,
0x4d8
,
0x46d
,
0x264
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x426
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x2fe
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x011
,
0xfff
,
0x05f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x10c
,
0x101
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x110
,
0xfff
,
0x044
,
0x304
,
0x361
,
0x404
,
0xfff
,
0x51b
,
0x099
,
0xfff
,
0x440
,
0xfff
,
0xfff
,
0xfff
,
0x222
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x1b5
,
0xfff
,
0x136
,
0x430
,
0xfff
,
0x1da
,
0xfff
,
0xfff
,
0xfff
,
0x043
,
0xfff
,
0x17c
,
0xfff
,
0xfff
,
0xfff
,
0x01c
,
0xfff
,
0xfff
,
0xfff
,
0x425
,
0x236
,
0xfff
,
0x317
,
0xfff
,
0xfff
,
0x437
,
0x3fc
,
0xfff
,
0x1f1
,
0xfff
,
0x324
,
0xfff
,
0xfff
,
0x0ca
,
0x306
,
0xfff
,
0x548
,
0xfff
,
0x46e
,
0xfff
,
0xfff
,
0xfff
,
0x4b8
,
0x1c2
,
0x286
,
0xfff
,
0xfff
,
0x087
,
0x18a
,
0x19f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x18c
,
0xfff
,
0x215
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x283
,
0xfff
,
0xfff
,
0xfff
,
0x126
,
0xfff
,
0xfff
,
0x370
,
0xfff
,
0x53f
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x31c
,
0xfff
,
0x4d1
,
0xfff
,
0xfff
,
0xfff
,
0x021
,
0xfff
,
0x157
,
0xfff
,
0xfff
,
0x028
,
0x16e
,
0xfff
,
0x421
,
0xfff
,
0x1c6
,
0xfff
,
0xfff
,
0x511
,
0xfff
,
0xfff
,
0x39c
,
0x46f
,
0x1b2
,
0xfff
,
0xfff
,
0x316
,
0xfff
,
0xfff
,
0x009
,
0xfff
,
0xfff
,
0x195
,
0xfff
,
0x240
,
0x546
,
0xfff
,
0xfff
,
0x520
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x454
,
0xfff
,
0xfff
,
0xfff
,
0x3f3
,
0xfff
,
0xfff
,
0x187
,
0xfff
,
0x4a9
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x51c
,
0x453
,
0x1e6
,
0xfff
,
0xfff
,
0xfff
,
0x1b0
,
0xfff
,
0x477
,
0xfff
,
0xfff
,
0xfff
,
0x4fe
,
0xfff
,
0x32f
,
0xfff
,
0xfff
,
0x15e
,
0x1d4
,
0xfff
,
0x0e5
,
0xfff
,
0xfff
,
0xfff
,
0x242
,
0x14b
,
0x046
,
0xfff
,
0x3f6
,
0x3bb
,
0x3e4
,
0xfff
,
0xfff
,
0x2e3
,
0xfff
,
0x245
,
0xfff
,
0x149
,
0xfff
,
0xfff
,
0xfff
,
0x2db
,
0xfff
,
0xfff
,
0x181
,
0xfff
,
0x089
,
0x2c5
,
0xfff
,
0x1f5
,
0xfff
,
0x2d6
,
0x507
,
0xfff
,
0x42d
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x080
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x3c3
,
0x320
,
0xfff
,
0x1e1
,
0xfff
,
0x0f5
,
0x13b
,
0xfff
,
0xfff
,
0xfff
,
0x003
,
0x4da
,
0xfff
,
0xfff
,
0xfff
,
0x42c
,
0xfff
,
0xfff
,
0x0cb
,
0xfff
,
0x536
,
0x2c3
,
0xfff
,
0xfff
,
0xfff
,
0xfff
,
0x199
,
0xfff
,
0xfff
,
0x0c0
,
0xfff
,
0x01e
,
0x497
,
0xfff
,
0xfff
,
0x3e5
,
0xfff
,
0xfff
,
0xfff
,
0x0cf
,
0xfff
,
0x2bd
,
0xfff
,
0x223
,
0xfff
,
0x3ff
,
0xfff
,
0x058
,
0x174
,
0x3ef
,
0xfff
,
0x002
};
static
unsigned
short
err_pos
(
unsigned
short
din
)
{
BUG_ON
(
din
>
4096
);
return
err_pos_lut
[
din
];
}
static
int
chk_no_err_only
(
unsigned
short
*
chk_syndrome_list
,
unsigned
short
*
err_info
)
{
if
((
chk_syndrome_list
[
0
]
|
chk_syndrome_list
[
1
]
|
chk_syndrome_list
[
2
]
|
chk_syndrome_list
[
3
]
|
chk_syndrome_list
[
4
]
|
chk_syndrome_list
[
5
]
|
chk_syndrome_list
[
6
]
|
chk_syndrome_list
[
7
])
!=
0x0
)
{
return
-
EINVAL
;
}
else
{
err_info
[
0
]
=
0x0
;
return
0
;
}
}
static
int
chk_1_err_only
(
unsigned
short
*
chk_syndrome_list
,
unsigned
short
*
err_info
)
{
unsigned
short
tmp0
,
tmp1
,
tmp2
,
tmp3
,
tmp4
,
tmp5
,
tmp6
;
tmp0
=
gf4096_mul
(
chk_syndrome_list
[
1
],
gf4096_inv
(
chk_syndrome_list
[
0
]));
tmp1
=
gf4096_mul
(
chk_syndrome_list
[
2
],
gf4096_inv
(
chk_syndrome_list
[
1
]));
tmp2
=
gf4096_mul
(
chk_syndrome_list
[
3
],
gf4096_inv
(
chk_syndrome_list
[
2
]));
tmp3
=
gf4096_mul
(
chk_syndrome_list
[
4
],
gf4096_inv
(
chk_syndrome_list
[
3
]));
tmp4
=
gf4096_mul
(
chk_syndrome_list
[
5
],
gf4096_inv
(
chk_syndrome_list
[
4
]));
tmp5
=
gf4096_mul
(
chk_syndrome_list
[
6
],
gf4096_inv
(
chk_syndrome_list
[
5
]));
tmp6
=
gf4096_mul
(
chk_syndrome_list
[
7
],
gf4096_inv
(
chk_syndrome_list
[
6
]));
if
((
tmp0
==
tmp1
)
&
(
tmp1
==
tmp2
)
&
(
tmp2
==
tmp3
)
&
(
tmp3
==
tmp4
)
&
(
tmp4
==
tmp5
)
&
(
tmp5
==
tmp6
))
{
err_info
[
0
]
=
0x1
;
// encode 1-symbol error as 0x1
err_info
[
1
]
=
err_pos
(
tmp0
);
err_info
[
1
]
=
(
unsigned
short
)(
0x55e
-
err_info
[
1
]);
err_info
[
5
]
=
chk_syndrome_list
[
0
];
return
0
;
}
else
return
-
EINVAL
;
}
static
int
chk_2_err_only
(
unsigned
short
*
chk_syndrome_list
,
unsigned
short
*
err_info
)
{
unsigned
short
tmp0
,
tmp1
,
tmp2
,
tmp3
,
tmp4
,
tmp5
,
tmp6
,
tmp7
;
unsigned
short
coefs
[
4
];
unsigned
short
err_pats
[
4
];
int
found_num_root
=
0
;
unsigned
short
bit2_root0
,
bit2_root1
;
unsigned
short
bit2_root0_inv
,
bit2_root1_inv
;
unsigned
short
err_loc_eqn
,
test_root
;
unsigned
short
bit2_loc0
,
bit2_loc1
;
unsigned
short
bit2_pat0
,
bit2_pat1
;
find_2x2_soln
(
chk_syndrome_list
[
1
],
chk_syndrome_list
[
0
],
chk_syndrome_list
[
2
],
chk_syndrome_list
[
1
],
chk_syndrome_list
[
2
],
chk_syndrome_list
[
3
],
coefs
);
for
(
test_root
=
0x1
;
test_root
<
0xfff
;
test_root
++
)
{
err_loc_eqn
=
gf4096_mul
(
coefs
[
1
],
gf4096_mul
(
test_root
,
test_root
))
^
gf4096_mul
(
coefs
[
0
],
test_root
)
^
0x1
;
if
(
err_loc_eqn
==
0x0
)
{
if
(
found_num_root
==
0
)
{
bit2_root0
=
test_root
;
found_num_root
=
1
;
}
else
if
(
found_num_root
==
1
)
{
bit2_root1
=
test_root
;
found_num_root
=
2
;
break
;
}
}
}
if
(
found_num_root
!=
2
)
return
-
EINVAL
;
else
{
bit2_root0_inv
=
gf4096_inv
(
bit2_root0
);
bit2_root1_inv
=
gf4096_inv
(
bit2_root1
);
find_2bit_err_pats
(
chk_syndrome_list
[
0
],
chk_syndrome_list
[
1
],
bit2_root0_inv
,
bit2_root1_inv
,
err_pats
);
bit2_pat0
=
err_pats
[
0
];
bit2_pat1
=
err_pats
[
1
];
//for(x+1)
tmp0
=
gf4096_mul
(
gf4096_mul
(
bit2_root0_inv
,
bit2_root0_inv
),
gf4096_mul
(
bit2_root0_inv
,
bit2_root0_inv
));
//rinv0^4
tmp1
=
gf4096_mul
(
bit2_root0_inv
,
tmp0
);
//rinv0^5
tmp2
=
gf4096_mul
(
bit2_root0_inv
,
tmp1
);
//rinv0^6
tmp3
=
gf4096_mul
(
bit2_root0_inv
,
tmp2
);
//rinv0^7
tmp4
=
gf4096_mul
(
gf4096_mul
(
bit2_root1_inv
,
bit2_root1_inv
),
gf4096_mul
(
bit2_root1_inv
,
bit2_root1_inv
));
//rinv1^4
tmp5
=
gf4096_mul
(
bit2_root1_inv
,
tmp4
);
//rinv1^5
tmp6
=
gf4096_mul
(
bit2_root1_inv
,
tmp5
);
//rinv1^6
tmp7
=
gf4096_mul
(
bit2_root1_inv
,
tmp6
);
//rinv1^7
//check if only 2-bit error
if
((
chk_syndrome_list
[
4
]
==
(
gf4096_mul
(
bit2_pat0
,
tmp0
)
^
gf4096_mul
(
bit2_pat1
,
tmp4
)))
&
(
chk_syndrome_list
[
5
]
==
(
gf4096_mul
(
bit2_pat0
,
tmp1
)
^
gf4096_mul
(
bit2_pat1
,
tmp5
)))
&
(
chk_syndrome_list
[
6
]
==
(
gf4096_mul
(
bit2_pat0
,
tmp2
)
^
gf4096_mul
(
bit2_pat1
,
tmp6
)))
&
(
chk_syndrome_list
[
7
]
==
(
gf4096_mul
(
bit2_pat0
,
tmp3
)
^
gf4096_mul
(
bit2_pat1
,
tmp7
))))
{
if
((
err_pos
(
bit2_root0_inv
)
==
0xfff
)
|
(
err_pos
(
bit2_root1_inv
)
==
0xfff
))
{
return
-
EINVAL
;
}
else
{
bit2_loc0
=
0x55e
-
err_pos
(
bit2_root0_inv
);
bit2_loc1
=
0x55e
-
err_pos
(
bit2_root1_inv
);
err_info
[
0
]
=
0x2
;
// encode 2-symbol error as 0x2
err_info
[
1
]
=
bit2_loc0
;
err_info
[
2
]
=
bit2_loc1
;
err_info
[
5
]
=
bit2_pat0
;
err_info
[
6
]
=
bit2_pat1
;
return
0
;
}
}
else
return
-
EINVAL
;
}
}
static
int
chk_3_err_only
(
unsigned
short
*
chk_syndrome_list
,
unsigned
short
*
err_info
)
{
unsigned
short
tmp0
,
tmp1
,
tmp2
,
tmp3
,
tmp4
,
tmp5
;
unsigned
short
coefs
[
4
];
unsigned
short
err_pats
[
4
];
int
found_num_root
=
0
;
unsigned
short
bit3_root0
,
bit3_root1
,
bit3_root2
;
unsigned
short
bit3_root0_inv
,
bit3_root1_inv
,
bit3_root2_inv
;
unsigned
short
err_loc_eqn
,
test_root
;
find_3bit_err_coefs
(
chk_syndrome_list
[
0
],
chk_syndrome_list
[
1
],
chk_syndrome_list
[
2
],
chk_syndrome_list
[
3
],
chk_syndrome_list
[
4
],
chk_syndrome_list
[
5
],
coefs
);
for
(
test_root
=
0x1
;
test_root
<
0xfff
;
test_root
++
)
{
err_loc_eqn
=
gf4096_mul
(
coefs
[
2
],
gf4096_mul
(
gf4096_mul
(
test_root
,
test_root
),
test_root
))
^
gf4096_mul
(
coefs
[
1
],
gf4096_mul
(
test_root
,
test_root
))
^
gf4096_mul
(
coefs
[
0
],
test_root
)
^
0x1
;
if
(
err_loc_eqn
==
0x0
)
{
if
(
found_num_root
==
0
)
{
bit3_root0
=
test_root
;
found_num_root
=
1
;
}
else
if
(
found_num_root
==
1
)
{
bit3_root1
=
test_root
;
found_num_root
=
2
;
}
else
if
(
found_num_root
==
2
)
{
bit3_root2
=
test_root
;
found_num_root
=
3
;
break
;
}
}
}
if
(
found_num_root
!=
3
)
return
-
EINVAL
;
else
{
bit3_root0_inv
=
gf4096_inv
(
bit3_root0
);
bit3_root1_inv
=
gf4096_inv
(
bit3_root1
);
bit3_root2_inv
=
gf4096_inv
(
bit3_root2
);
find_3bit_err_pats
(
chk_syndrome_list
[
0
],
chk_syndrome_list
[
1
],
chk_syndrome_list
[
2
],
bit3_root0_inv
,
bit3_root1_inv
,
bit3_root2_inv
,
err_pats
);
//check if only 3-bit error
tmp0
=
gf4096_mul
(
bit3_root0_inv
,
bit3_root0_inv
);
tmp0
=
gf4096_mul
(
tmp0
,
tmp0
);
tmp0
=
gf4096_mul
(
tmp0
,
bit3_root0_inv
);
tmp0
=
gf4096_mul
(
tmp0
,
bit3_root0_inv
);
//rinv0^6
tmp1
=
gf4096_mul
(
tmp0
,
bit3_root0_inv
);
//rinv0^7
tmp2
=
gf4096_mul
(
bit3_root1_inv
,
bit3_root1_inv
);
tmp2
=
gf4096_mul
(
tmp2
,
tmp2
);
tmp2
=
gf4096_mul
(
tmp2
,
bit3_root1_inv
);
tmp2
=
gf4096_mul
(
tmp2
,
bit3_root1_inv
);
//rinv1^6
tmp3
=
gf4096_mul
(
tmp2
,
bit3_root1_inv
);
//rinv1^7
tmp4
=
gf4096_mul
(
bit3_root2_inv
,
bit3_root2_inv
);
tmp4
=
gf4096_mul
(
tmp4
,
tmp4
);
tmp4
=
gf4096_mul
(
tmp4
,
bit3_root2_inv
);
tmp4
=
gf4096_mul
(
tmp4
,
bit3_root2_inv
);
//rinv2^6
tmp5
=
gf4096_mul
(
tmp4
,
bit3_root2_inv
);
//rinv2^7
//check if only 3 errors
if
((
chk_syndrome_list
[
6
]
==
(
gf4096_mul
(
err_pats
[
0
],
tmp0
)
^
gf4096_mul
(
err_pats
[
1
],
tmp2
)
^
gf4096_mul
(
err_pats
[
2
],
tmp4
)))
&
(
chk_syndrome_list
[
7
]
==
(
gf4096_mul
(
err_pats
[
0
],
tmp1
)
^
gf4096_mul
(
err_pats
[
1
],
tmp3
)
^
gf4096_mul
(
err_pats
[
2
],
tmp5
))))
{
if
((
err_pos
(
bit3_root0_inv
)
==
0xfff
)
|
(
err_pos
(
bit3_root1_inv
)
==
0xfff
)
|
(
err_pos
(
bit3_root2_inv
)
==
0xfff
))
{
return
-
EINVAL
;
}
else
{
err_info
[
0
]
=
0x3
;
err_info
[
1
]
=
(
0x55e
-
err_pos
(
bit3_root0_inv
));
err_info
[
2
]
=
(
0x55e
-
err_pos
(
bit3_root1_inv
));
err_info
[
3
]
=
(
0x55e
-
err_pos
(
bit3_root2_inv
));
err_info
[
5
]
=
err_pats
[
0
];
err_info
[
6
]
=
err_pats
[
1
];
err_info
[
7
]
=
err_pats
[
2
];
return
0
;
}
}
else
return
-
EINVAL
;
}
}
static
int
chk_4_err_only
(
unsigned
short
*
chk_syndrome_list
,
unsigned
short
*
err_info
)
{
unsigned
short
coefs
[
4
];
unsigned
short
err_pats
[
4
];
int
found_num_root
=
0
;
unsigned
short
bit4_root0
,
bit4_root1
,
bit4_root2
,
bit4_root3
;
unsigned
short
bit4_root0_inv
,
bit4_root1_inv
,
bit4_root2_inv
,
bit4_root3_inv
;
unsigned
short
err_loc_eqn
,
test_root
;
find_4bit_err_coefs
(
chk_syndrome_list
[
0
],
chk_syndrome_list
[
1
],
chk_syndrome_list
[
2
],
chk_syndrome_list
[
3
],
chk_syndrome_list
[
4
],
chk_syndrome_list
[
5
],
chk_syndrome_list
[
6
],
chk_syndrome_list
[
7
],
coefs
);
for
(
test_root
=
0x1
;
test_root
<
0xfff
;
test_root
++
)
{
err_loc_eqn
=
gf4096_mul
(
coefs
[
3
],
gf4096_mul
(
gf4096_mul
(
gf4096_mul
(
test_root
,
test_root
),
test_root
),
test_root
))
^
gf4096_mul
(
coefs
[
2
],
gf4096_mul
(
gf4096_mul
(
test_root
,
test_root
),
test_root
))
^
gf4096_mul
(
coefs
[
1
],
gf4096_mul
(
test_root
,
test_root
))
^
gf4096_mul
(
coefs
[
0
],
test_root
)
^
0x1
;
if
(
err_loc_eqn
==
0x0
)
{
if
(
found_num_root
==
0
)
{
bit4_root0
=
test_root
;
found_num_root
=
1
;
}
else
if
(
found_num_root
==
1
)
{
bit4_root1
=
test_root
;
found_num_root
=
2
;
}
else
if
(
found_num_root
==
2
)
{
bit4_root2
=
test_root
;
found_num_root
=
3
;
}
else
{
found_num_root
=
4
;
bit4_root3
=
test_root
;
break
;
}
}
}
if
(
found_num_root
!=
4
)
{
return
-
EINVAL
;
}
else
{
bit4_root0_inv
=
gf4096_inv
(
bit4_root0
);
bit4_root1_inv
=
gf4096_inv
(
bit4_root1
);
bit4_root2_inv
=
gf4096_inv
(
bit4_root2
);
bit4_root3_inv
=
gf4096_inv
(
bit4_root3
);
find_4bit_err_pats
(
chk_syndrome_list
[
0
],
chk_syndrome_list
[
1
],
chk_syndrome_list
[
2
],
chk_syndrome_list
[
3
],
bit4_root0_inv
,
bit4_root1_inv
,
bit4_root2_inv
,
bit4_root3_inv
,
err_pats
);
err_info
[
0
]
=
0x4
;
err_info
[
1
]
=
(
0x55e
-
err_pos
(
bit4_root0_inv
));
err_info
[
2
]
=
(
0x55e
-
err_pos
(
bit4_root1_inv
));
err_info
[
3
]
=
(
0x55e
-
err_pos
(
bit4_root2_inv
));
err_info
[
4
]
=
(
0x55e
-
err_pos
(
bit4_root3_inv
));
err_info
[
5
]
=
err_pats
[
0
];
err_info
[
6
]
=
err_pats
[
1
];
err_info
[
7
]
=
err_pats
[
2
];
err_info
[
8
]
=
err_pats
[
3
];
return
0
;
}
}
void
correct_12bit_symbol
(
unsigned
char
*
buf
,
unsigned
short
sym
,
unsigned
short
val
)
{
if
(
unlikely
(
sym
>
1366
))
{
printk
(
KERN_ERR
"Error: symbol %d out of range; cannot correct
\n
"
,
sym
);
}
else
if
(
sym
==
0
)
{
buf
[
0
]
^=
val
;
}
else
if
(
sym
&
1
)
{
buf
[
1
+
(
3
*
(
sym
-
1
))
/
2
]
^=
(
val
>>
4
);
buf
[
2
+
(
3
*
(
sym
-
1
))
/
2
]
^=
((
val
&
0xf
)
<<
4
);
}
else
{
buf
[
2
+
(
3
*
(
sym
-
2
))
/
2
]
^=
(
val
>>
8
);
buf
[
3
+
(
3
*
(
sym
-
2
))
/
2
]
^=
(
val
&
0xff
);
}
}
static
int
debugecc
=
0
;
module_param
(
debugecc
,
int
,
0644
);
int
cafe_correct_ecc
(
unsigned
char
*
buf
,
unsigned
short
*
chk_syndrome_list
)
{
unsigned
short
err_info
[
9
];
int
i
;
if
(
debugecc
)
{
printk
(
KERN_WARNING
"cafe_correct_ecc invoked. Syndromes %x %x %x %x %x %x %x %x
\n
"
,
chk_syndrome_list
[
0
],
chk_syndrome_list
[
1
],
chk_syndrome_list
[
2
],
chk_syndrome_list
[
3
],
chk_syndrome_list
[
4
],
chk_syndrome_list
[
5
],
chk_syndrome_list
[
6
],
chk_syndrome_list
[
7
]);
for
(
i
=
0
;
i
<
2048
;
i
+=
16
)
{
printk
(
KERN_WARNING
"D %04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
i
,
buf
[
i
],
buf
[
i
+
1
],
buf
[
i
+
2
],
buf
[
i
+
3
],
buf
[
i
+
4
],
buf
[
i
+
5
],
buf
[
i
+
6
],
buf
[
i
+
7
],
buf
[
i
+
8
],
buf
[
i
+
9
],
buf
[
i
+
10
],
buf
[
i
+
11
],
buf
[
i
+
12
],
buf
[
i
+
13
],
buf
[
i
+
14
],
buf
[
i
+
15
]);
}
for
(
;
i
<
2112
;
i
+=
16
)
{
printk
(
KERN_WARNING
"O %02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
i
-
2048
,
buf
[
i
],
buf
[
i
+
1
],
buf
[
i
+
2
],
buf
[
i
+
3
],
buf
[
i
+
4
],
buf
[
i
+
5
],
buf
[
i
+
6
],
buf
[
i
+
7
],
buf
[
i
+
8
],
buf
[
i
+
9
],
buf
[
i
+
10
],
buf
[
i
+
11
],
buf
[
i
+
12
],
buf
[
i
+
13
],
buf
[
i
+
14
],
buf
[
i
+
15
]);
}
}
if
(
chk_no_err_only
(
chk_syndrome_list
,
err_info
)
&&
chk_1_err_only
(
chk_syndrome_list
,
err_info
)
&&
chk_2_err_only
(
chk_syndrome_list
,
err_info
)
&&
chk_3_err_only
(
chk_syndrome_list
,
err_info
)
&&
chk_4_err_only
(
chk_syndrome_list
,
err_info
))
{
return
-
EIO
;
}
for
(
i
=
0
;
i
<
err_info
[
0
];
i
++
)
{
if
(
debugecc
)
printk
(
KERN_WARNING
"Correct symbol %d with 0x%03x
\n
"
,
err_info
[
1
+
i
],
err_info
[
5
+
i
]);
correct_12bit_symbol
(
buf
,
err_info
[
1
+
i
],
err_info
[
5
+
i
]);
}
return
err_info
[
0
];
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment