Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
linux-elphel
Commits
9de93068
Commit
9de93068
authored
May 06, 2016
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix pointer convertion error in jpeghead
WIP: hw pointer offset error is still there
parent
2fd99c36
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
67 additions
and
7 deletions
+67
-7
circbuf.c
src/drivers/elphel/circbuf.c
+2
-2
elphel393-mem.c
src/drivers/elphel/elphel393-mem.c
+39
-0
sensor_common.c
src/drivers/elphel/sensor_common.c
+26
-5
No files found.
src/drivers/elphel/circbuf.c
View file @
9de93068
...
@@ -184,8 +184,8 @@ loff_t circbuf_all_lseek(struct file *file, loff_t offset, int orig)
...
@@ -184,8 +184,8 @@ loff_t circbuf_all_lseek(struct file *file, loff_t offset, int orig)
return
circbuf_lseek
(
file
,
offset
,
orig
);
return
circbuf_lseek
(
file
,
offset
,
orig
);
case
JPEGHEAD_MINOR
:
case
JPEGHEAD_MINOR
:
if
(
orig
==
SEEK_END
&&
offset
>
0
)
{
if
(
orig
==
SEEK_END
&&
offset
>
0
)
{
rp
=
BYTE2DW
(
offset
)
&
(
~
7
);
// convert to index to long, align to 32-bytes
rp
=
BYTE2DW
(
X393_BUFFSUB
(
offset
,
CHUNK_SIZE
)
)
&
(
~
7
);
// convert to index to long, align to 32-bytes
fp
=
(
struct
interframe_params_t
*
)
&
circbuf_priv
[
chn
].
buf_ptr
[
X393_BUFFSUB
(
rp
,
8
)
];
fp
=
(
struct
interframe_params_t
*
)
&
circbuf_priv
[
chn
].
buf_ptr
[
rp
];
}
}
return
jpeghead_lseek
(
file
,
offset
,
orig
,
fp
);
return
jpeghead_lseek
(
file
,
offset
,
orig
,
fp
);
case
HUFFMAN_MINOR
:
case
HUFFMAN_MINOR
:
...
...
src/drivers/elphel/elphel393-mem.c
View file @
9de93068
...
@@ -310,6 +310,38 @@ static ssize_t sync_for_device_bidir(struct device *dev, struct device_attribute
...
@@ -310,6 +310,38 @@ static ssize_t sync_for_device_bidir(struct device *dev, struct device_attribute
return
count
;
return
count
;
}
}
static
ssize_t
flush_cpu_cache
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
const
int
buff_size
=
0x1000000
;
const
int
buff_start_offset
=
0x100000
;
unsigned
int
chn
;
int
start_offset
,
end_offset
;
int
num_items
;
dma_addr_t
phys_addr_start
,
phys_addr_end
;
num_items
=
sscanf
(
buf
,
"%u:%d:%d"
,
&
chn
,
&
start_offset
,
&
end_offset
);
if
(
num_items
==
3
)
{
// invalidate L2 caches
if
(
end_offset
>
start_offset
)
{
// handle single buffer case
phys_addr_start
=
_elphel_buf
.
paddr
+
buff_start_offset
+
chn
*
buff_size
+
start_offset
;
phys_addr_end
=
_elphel_buf
.
paddr
+
buff_start_offset
+
chn
*
buff_size
+
end_offset
-
1
;
outer_inv_range
(
phys_addr_start
,
phys_addr_end
);
}
else
{
// handle split buffer case when pointer rolls over the end
// first, process the peace at the end of the buffer
phys_addr_start
=
_elphel_buf
.
paddr
+
buff_start_offset
+
chn
*
buff_size
+
start_offset
;
phys_addr_end
=
_elphel_buf
.
paddr
+
buff_start_offset
+
++
chn
*
buff_size
-
1
;
outer_inv_range
(
phys_addr_start
,
phys_addr_end
);
// second, process the peace at the start of the buffer
phys_addr_start
=
_elphel_buf
.
paddr
+
buff_start_offset
+
chn
*
buff_size
;
phys_addr_end
=
_elphel_buf
.
paddr
+
buff_start_offset
+
chn
*
buff_size
+
end_offset
-
1
;
outer_inv_range
(
phys_addr_start
,
phys_addr_end
);
}
}
return
count
;
}
static
ssize_t
get_sync_for_device_h2d
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
static
ssize_t
get_sync_for_device_h2d
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
{
...
@@ -335,6 +367,11 @@ static ssize_t get_sync_for_cpu_bidir(struct device *dev, struct device_attribut
...
@@ -335,6 +367,11 @@ static ssize_t get_sync_for_cpu_bidir(struct device *dev, struct device_attribut
{
{
return
sprintf
(
buf
,
"Write address/length pair into this file to hand this region of the bidirectional DMA buffer to CPU (before CPU reads).
\n
"
);
return
sprintf
(
buf
,
"Write address/length pair into this file to hand this region of the bidirectional DMA buffer to CPU (before CPU reads).
\n
"
);
}
}
static
ssize_t
get_flush_cpu_cache
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
return
sprintf
(
buf
,
"Write command and address into this file to flush CPU caches. Format 'chn:start_offset:end_offset' where "
"'chn' is sensor channel, 'start_offset' and 'end_offset' are start and end data offsets in circbuf
\n
"
);
}
static
DEVICE_ATTR
(
buffer_address
,
SYSFS_PERMISSIONS
&
SYSFS_READONLY
,
get_paddr
,
NULL
);
static
DEVICE_ATTR
(
buffer_address
,
SYSFS_PERMISSIONS
&
SYSFS_READONLY
,
get_paddr
,
NULL
);
static
DEVICE_ATTR
(
buffer_pages
,
SYSFS_PERMISSIONS
&
SYSFS_READONLY
,
get_size
,
NULL
);
static
DEVICE_ATTR
(
buffer_pages
,
SYSFS_PERMISSIONS
&
SYSFS_READONLY
,
get_size
,
NULL
);
...
@@ -351,6 +388,7 @@ static DEVICE_ATTR(sync_for_cpu_d2h, SYSFS_PERMISSIONS,
...
@@ -351,6 +388,7 @@ static DEVICE_ATTR(sync_for_cpu_d2h, SYSFS_PERMISSIONS,
static
DEVICE_ATTR
(
sync_for_device_d2h
,
SYSFS_PERMISSIONS
,
get_sync_for_device_d2h
,
sync_for_device_d2h
);
static
DEVICE_ATTR
(
sync_for_device_d2h
,
SYSFS_PERMISSIONS
,
get_sync_for_device_d2h
,
sync_for_device_d2h
);
static
DEVICE_ATTR
(
sync_for_cpu_bidir
,
SYSFS_PERMISSIONS
,
get_sync_for_cpu_bidir
,
sync_for_cpu_bidir
);
static
DEVICE_ATTR
(
sync_for_cpu_bidir
,
SYSFS_PERMISSIONS
,
get_sync_for_cpu_bidir
,
sync_for_cpu_bidir
);
static
DEVICE_ATTR
(
sync_for_device_bidir
,
SYSFS_PERMISSIONS
,
get_sync_for_device_bidir
,
sync_for_device_bidir
);
static
DEVICE_ATTR
(
sync_for_device_bidir
,
SYSFS_PERMISSIONS
,
get_sync_for_device_bidir
,
sync_for_device_bidir
);
static
DEVICE_ATTR
(
flush_cpu_cache
,
SYSFS_PERMISSIONS
,
get_flush_cpu_cache
,
flush_cpu_cache
);
static
struct
attribute
*
root_dev_attrs
[]
=
{
static
struct
attribute
*
root_dev_attrs
[]
=
{
&
dev_attr_buffer_address
.
attr
,
&
dev_attr_buffer_address
.
attr
,
...
@@ -368,6 +406,7 @@ static struct attribute *root_dev_attrs[] = {
...
@@ -368,6 +406,7 @@ static struct attribute *root_dev_attrs[] = {
&
dev_attr_sync_for_device_d2h
.
attr
,
&
dev_attr_sync_for_device_d2h
.
attr
,
&
dev_attr_sync_for_cpu_bidir
.
attr
,
&
dev_attr_sync_for_cpu_bidir
.
attr
,
&
dev_attr_sync_for_device_bidir
.
attr
,
&
dev_attr_sync_for_device_bidir
.
attr
,
&
dev_attr_flush_cpu_cache
.
attr
,
NULL
NULL
};
};
...
...
src/drivers/elphel/sensor_common.c
View file @
9de93068
...
@@ -244,6 +244,7 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
...
@@ -244,6 +244,7 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
{
{
phys_addr_t
phys_addr
;
phys_addr_t
phys_addr
;
void
*
virt_addr
;
void
*
virt_addr
;
int
prev_dword
;
int
xferred
;
/// number of 32-byte chunks transferred since compressor was reset
int
xferred
;
/// number of 32-byte chunks transferred since compressor was reset
x393_afimux_status_t
stat
=
x393_afimux0_status
(
jptr
->
chn_num
);
x393_afimux_status_t
stat
=
x393_afimux0_status
(
jptr
->
chn_num
);
...
@@ -268,12 +269,32 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
...
@@ -268,12 +269,32 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
* end of buffer and 32 zero bytes start from the beginning of the buffer. HW pointer in this case should
* end of buffer and 32 zero bytes start from the beginning of the buffer. HW pointer in this case should
* be 0x20, but it is 0x00 in fact. Try to detect this situation and correct the offset.
* be 0x20, but it is 0x00 in fact. Try to detect this situation and correct the offset.
*/
*/
if
(
jptr
->
jpeg_wp
==
0
&&
if
(
jptr
->
jpeg_wp
==
0
)
{
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
[
jptr
->
jpeg_wp
]
==
0x00
&&
// if pointer is set incorrectly, then we need two invalidate two cache lines in order to
(
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
[
jptr
->
jpeg_wp
-
1
]
&
MARKER_FF
)
==
MARKER_FF
)
{
// estimate the situation correctly: one line after the pointer, which should be the line of
// 32 zeros, and one line before the pointer, which should be the last line of the frame. If this is not done
// then the data read from memory can be incorrect and error detection will give false result. Barrier is set to
// prevent compiler from reordering operations.
phys_addr
=
circbuf_priv_ptr
[
jptr
->
chn_num
].
phys_addr
;
virt_addr
=
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
;
dev_dbg
(
NULL
,
"from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p
\n
"
,
phys_addr
,
virt_addr
);
outer_inv_range
(
phys_addr
,
phys_addr
+
(
CHUNK_SIZE
-
1
));
__cpuc_flush_dcache_area
(
virt_addr
,
CHUNK_SIZE
);
phys_addr
=
circbuf_priv_ptr
[
jptr
->
chn_num
].
phys_addr
+
CCAM_DMA_SIZE
-
CHUNK_SIZE
;
virt_addr
=
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
+
BYTE2DW
(
CCAM_DMA_SIZE
-
CHUNK_SIZE
);
outer_inv_range
(
phys_addr
,
phys_addr
+
(
CHUNK_SIZE
-
1
));
__cpuc_flush_dcache_area
(
virt_addr
,
CHUNK_SIZE
);
dev_dbg
(
NULL
,
"from updateIRQJPEG_wp: phys_addr = 0x%x, virt_addr = 0x%p
\n
"
,
phys_addr
,
virt_addr
);
barrier
();
prev_dword
=
X393_BUFFSUB
(
DW2BYTE
(
jptr
->
jpeg_wp
),
4
);
dev_dbg
(
NULL
,
"circbuf_priv_ptr[jptr->chn_num].buf_ptr[jptr->jpeg_wp] = 0x%x
\n
"
,
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
[
jptr
->
jpeg_wp
]);
dev_dbg
(
NULL
,
"circbuf_priv_ptr[jptr->chn_num].buf_ptr[BYTE2DW(prev_dword)] = 0x%x
\n
"
,
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
[
BYTE2DW
(
prev_dword
)]);
if
(
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
[
jptr
->
jpeg_wp
]
==
0x00
&&
(
circbuf_priv_ptr
[
jptr
->
chn_num
].
buf_ptr
[
BYTE2DW
(
prev_dword
)]
&
MARKER_FF
)
==
MARKER_FF
)
{
jptr
->
jpeg_wp
+=
INTERFRAME_PARAMS_SZ
;
jptr
->
jpeg_wp
+=
INTERFRAME_PARAMS_SZ
;
corrected_offset
[
jptr
->
chn_num
]
+=
1
;
corrected_offset
[
jptr
->
chn_num
]
+=
1
;
}
}
}
// invalidate CPU L1 and L2 caches
// invalidate CPU L1 and L2 caches
// the code below was used to find cache coherence issues
// the code below was used to find cache coherence issues
...
...
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