Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
chickadee
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Matija Benko
chickadee
Commits
900ce48f
Commit
900ce48f
authored
Mar 21, 2018
by
Eddie Kohler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better interface to ahcistate::read/write.
parent
701ab8f9
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
37 additions
and
50 deletions
+37
-50
k-chkfs.cc
k-chkfs.cc
+1
-2
k-devices.cc
k-devices.cc
+23
-45
k-devices.hh
k-devices.hh
+13
-3
No files found.
k-chkfs.cc
View file @
900ce48f
...
...
@@ -58,8 +58,7 @@ void* bufcache::get_disk_block(chickadeefs::blocknum_t bn,
e_
[
i
].
flags_
|=
bufentry
::
f_loading
;
e_
[
i
].
lock_
.
unlock
(
irqs
);
sata_disk
->
read
(
bn
*
(
chickadeefs
::
blocksize
/
sata_disk
->
sectorsize
),
x
,
chickadeefs
::
blocksize
/
sata_disk
->
sectorsize
);
(
x
,
chickadeefs
::
blocksize
,
bn
*
chickadeefs
::
blocksize
);
irqs
=
e_
[
i
].
lock_
.
lock
();
e_
[
i
].
flags_
=
(
e_
[
i
].
flags_
&
~
bufentry
::
f_loading
)
|
bufentry
::
f_loaded
;
...
...
k-devices.cc
View file @
900ce48f
...
...
@@ -262,15 +262,20 @@ inline void ahcistate::clear(int slot) {
// ahcistate::push_buffer(slot, buf, sz)
// Append a data buffer to the buffers relevant for the next command.
inline
void
ahcistate
::
push_buffer
(
int
slot
,
void
*
buf
,
size_t
sz
)
{
// check requirements on address and size
uint64_t
pa
=
kptr2pa
(
buf
);
assert
((
pa
&
1
)
==
0
&&
(
sz
&
1
)
==
0
);
// word-aligned
assert
(
sz
>
0
&&
sz
<=
(
64U
<<
10
));
// >0, <64KiB
assert
(
pa
<=
0x100000000UL
);
// low physical memory
assert
((
pa
^
(
pa
+
sz
-
1
))
<
(
64U
<<
10
));
// within aligned 64KiB
// check slot availability
assert
(
unsigned
(
slot
)
<
unsigned
(
nslots_
));
assert
(
dma_
.
ch
[
slot
].
nbuf
<
arraysize
(
dma_
.
ct
[
slot
].
buf
));
int
nbuf
=
dma_
.
ch
[
slot
].
nbuf
;
uint64_t
pa
=
kptr2pa
(
buf
);
assert
((
pa
&
1
)
==
0
&&
(
sz
&
1
)
==
0
&&
sz
>
0
);
int
nbuf
=
dma_
.
ch
[
slot
].
nbuf
;
dma_
.
ct
[
slot
].
buf
[
nbuf
].
pa
=
pa
;
dma_
.
ct
[
slot
].
buf
[
nbuf
].
maxbyte
=
sz
-
1
;
dma_
.
ch
[
slot
].
nbuf
=
nbuf
+
1
;
dma_
.
ch
[
slot
].
buf_byte_pos
+=
sz
;
}
...
...
@@ -329,44 +334,17 @@ inline void ahcistate::acknowledge(int slot, int result) {
// FUNCTIONS FOR READING AND WRITING BLOCKS
int
ahcistate
::
read
(
size_t
sector
,
void
*
buf
,
size_t
nsectors
)
{
uintptr_t
pa
=
kptr2pa
(
buf
);
assert
(
pa
<=
0x100000000UL
);
assert
(
nsectors
>
0
&&
nsectors
<=
(
64U
<<
10
)
/
sectorsize
);
assert
(
nsectors
<=
nslots_
);
assert
((
pa
^
(
pa
+
nsectors
*
sectorsize
-
1
))
<
(
64U
<<
10
));
// obtain lock
proc
*
p
=
current
();
auto
irqs
=
lock_
.
lock
();
// block until ready for command
waiter
(
p
).
block_until
(
wq_
,
[
&
]
()
{
return
!
slots_outstanding_mask_
;
},
lock_
,
irqs
);
// send command, record buffer and status storage
int
r
=
E_AGAIN
;
clear
(
0
);
push_buffer
(
0
,
buf
,
nsectors
*
sectorsize
);
issue_ncq
(
0
,
cmd_read_fpdma_queued
,
sector
);
slot_status_
[
0
]
=
&
r
;
lock_
.
unlock
(
irqs
);
// wait for response
waiter
(
p
).
block_until
(
wq_
,
[
&
]
()
{
return
r
!=
E_AGAIN
;
});
return
0
;
}
// ahcistate::read_or_write(command, buf, sz, off)
// Issue an NCQ read or write command `command`. Read or write
// `sz` bytes of data to or from `buf`, starting at disk offset
// `off`. `sz` and `off` are measured in bytes, but must be
// sector-aligned (i.e., multiples of `ahcistate::sectorsize`).
// Can block. Returns 0 on success and an error code on failure.
int
ahcistate
::
write
(
size_t
sector
,
const
void
*
buf
,
size_t
nsectors
)
{
uintptr_t
pa
=
kptr2pa
(
buf
);
assert
(
pa
<=
0x100000000UL
);
assert
(
nsectors
>
0
&&
nsectors
<=
(
64U
<<
10
)
/
sectorsize
);
assert
(
nsectors
<=
nslots_
);
assert
((
pa
^
(
pa
+
nsectors
*
sectorsize
-
1
))
<
(
64U
<<
10
));
int
ahcistate
::
read_or_write
(
idecommand
command
,
void
*
buf
,
size_t
sz
,
size_t
off
)
{
// `sz` and `off` must be sector-aligned
assert
(
sz
%
sectorsize
==
0
&&
off
%
sectorsize
==
0
);
// obtain lock
proc
*
p
=
current
();
...
...
@@ -378,10 +356,10 @@ int ahcistate::write(size_t sector, const void* buf, size_t nsectors) {
},
lock_
,
irqs
);
// send command, record buffer and status storage
int
r
=
E_AGAIN
;
volatile
int
r
=
E_AGAIN
;
clear
(
0
);
push_buffer
(
0
,
const_cast
<
void
*>
(
buf
),
nsectors
*
sectorsize
);
issue_ncq
(
0
,
c
md_write_fpdma_queued
,
sector
);
push_buffer
(
0
,
buf
,
sz
);
issue_ncq
(
0
,
c
ommand
,
off
/
sectorsize
);
slot_status_
[
0
]
=
&
r
;
lock_
.
unlock
(
irqs
);
...
...
@@ -390,7 +368,7 @@ int ahcistate::write(size_t sector, const void* buf, size_t nsectors) {
waiter
(
p
).
block_until
(
wq_
,
[
&
]
()
{
return
r
!=
E_AGAIN
;
});
return
0
;
return
r
;
}
...
...
k-devices.hh
View file @
900ce48f
...
...
@@ -219,7 +219,7 @@ struct ahcistate {
wait_queue
wq_
;
unsigned
nslots_available_
;
// # slots available for commands
uint32_t
slots_outstanding_mask_
;
// 1 == that slot is used
int
*
slot_status_
[
32
];
// ptrs to status storage, one per slot
volatile
int
*
slot_status_
[
32
];
// ptrs to status storage, one per slot
ahcistate
(
int
pci_addr
,
int
sata_port
,
volatile
regs
*
mr
);
...
...
@@ -227,8 +227,9 @@ struct ahcistate {
static
ahcistate
*
find
(
int
pci_addr
=
0
,
int
sata_port
=
0
);
// high-level functions (they block)
int
read
(
size_t
sector
,
void
*
buf
,
size_t
nsectors
);
int
write
(
size_t
sector
,
const
void
*
buf
,
size_t
nsectors
);
inline
int
read
(
void
*
buf
,
size_t
sz
,
size_t
off
);
inline
int
write
(
const
void
*
buf
,
size_t
sz
,
size_t
off
);
int
read_or_write
(
idecommand
cmd
,
void
*
buf
,
size_t
sz
,
size_t
off
);
// interrupt handlers
void
handle_interrupt
();
...
...
@@ -272,4 +273,13 @@ inline memfile* memfile::initfs_lookup(const char* name) {
return
initfs_lookup
(
name
,
strlen
(
name
));
}
inline
int
ahcistate
::
read
(
void
*
buf
,
size_t
sz
,
size_t
off
)
{
return
read_or_write
(
cmd_read_fpdma_queued
,
buf
,
sz
,
off
);
}
inline
int
ahcistate
::
write
(
const
void
*
buf
,
size_t
sz
,
size_t
off
)
{
return
read_or_write
(
cmd_write_fpdma_queued
,
const_cast
<
void
*>
(
buf
),
sz
,
off
);
}
#endif
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