Commit 59e3df6e authored by Soby Mathew's avatar Soby Mathew Committed by TrustedFirmware Code Review
Browse files

Merge "doc: Complete the storage abstraction layer doc" into integration

parents 7871fff2 dbeace10
......@@ -2762,14 +2762,12 @@ can be obtained from http://github.com/freebsd/freebsd.
Storage abstraction layer
-------------------------
In order to improve platform independence and portability an storage abstraction
layer is used to load data from non-volatile platform storage.
In order to improve platform independence and portability a storage abstraction
layer is used to load data from non-volatile platform storage. Currently
storage access is only required by BL1 and BL2 phases and performed inside the
``load_image()`` function in ``bl_common.c``.
Each platform should register devices and their drivers via the Storage layer.
These drivers then need to be initialized by bootloader phases as
required in their respective ``blx_platform_setup()`` functions. Currently
storage access is only required by BL1 and BL2 phases. The ``load_image()``
function uses the storage layer to access non-volatile platform storage.
.. uml:: ../resources/diagrams/plantuml/io_framework_usage_overview.puml
It is mandatory to implement at least one storage driver. For the Arm
development platforms the Firmware Image Package (FIP) driver is provided as
......@@ -2779,13 +2777,25 @@ section in the `User Guide`_). The storage layer is described in the header file
is in ``drivers/io/io_storage.c`` and the driver files are located in
``drivers/io/``.
.. uml:: ../resources/diagrams/plantuml/io_arm_class_diagram.puml
Each IO driver must provide ``io_dev_*`` structures, as described in
``drivers/io/io_driver.h``. These are returned via a mandatory registration
function that is called on platform initialization. The semi-hosting driver
implementation in ``io_semihosting.c`` can be used as an example.
The Storage layer provides mechanisms to initialize storage devices before
IO operations are called. The basic operations supported by the layer
Each platform should register devices and their drivers via the storage
abstraction layer. These drivers then need to be initialized by bootloader
phases as required in their respective ``blx_platform_setup()`` functions.
.. uml:: ../resources/diagrams/plantuml/io_dev_registration.puml
The storage abstraction layer provides mechanisms (``io_dev_init()``) to
initialize storage devices before IO operations are called.
.. uml:: ../resources/diagrams/plantuml/io_dev_init_and_check.puml
The basic operations supported by the layer
include ``open()``, ``close()``, ``read()``, ``write()``, ``size()`` and ``seek()``.
Drivers do not have to implement all operations, but each platform must
provide at least one driver for a device capable of supporting generic
......
@startuml
package arm_io_storage {
class plat_io_policy {
dev_handle : uintptr_t*
image_spec : uintptr_t
{abstract} check() : fctptr
}
class FIP_IMAGE_ID {
memmap_dev_handle
fip_block_spec
open_memmap()
}
class BL2_IMAGE_ID{
fip_dev_handle
bl2_uuid_spec
open_fip()
}
class xxx_IMAGE_ID{
fip_dev_handle
xxx_uuid_spec
open_fip()
}
class arm_io_storage {
fip_dev_con : io_dev_connector_t*
fip_dev_handle : uintptr_t
memmap_dev_con : io_dev_connector_t*
memmap_dev_handle : uintptr_t
fip_block_spec : io_block_spec_t
policies : plat_io_policy[1..*]
-open_fip()
-open_memmap()
+arm_io_setup()
+plat_get_image_source()
}
FIP_IMAGE_ID -up-|> plat_io_policy
BL2_IMAGE_ID -up-|> plat_io_policy
xxx_IMAGE_ID -up-|> plat_io_policy
arm_io_storage *-"1..*" plat_io_policy
}
package IO {
class io_storage {
io_dev_open()
io_dev_init()
io_dev_close()
.. synchronous operations ..
io_open()
io_seek()
io_size()
io_read()
io_write()
io_close()
io_register_device()
}
class io_fip {
register_io_dev_fip()
.. io_dev_funcs_t interface ..
fip_dev_funcs : io_dev_funcs_t
}
class io_memmap {
register_io_dev_memmap()
.. io_dev_funcs_t interface ..
memmap_dev_funcs : io_dev_funcs_t
}
interface io_driver {
io_entity_t
io_dev_info_t
.. io_dev_connector_t interface ..
dev_open()
.. io_dev_funcs_t interface ..
type()
open()
seek()
size()
read()
write()
close()
dev_init()
dev_close()
io_register_device()
}
}
arm_io_storage .. io_driver
arm_io_storage .. io_fip
arm_io_storage .. io_memmap
arm_io_storage .. io_storage
@enduml
@startuml
participant arm_io_storage order 1
participant io_storage order 2
-> arm_io_storage : plat_get_image_source(image_id, &dev_handle, &image_spec)
group init and check device (image_id)
alt image_id = BL2_IMAGE_ID
note over arm_io_storage
get BL2_IMAGE_ID policy:
- fip_dev_handle
- open_fip()
end note
opt policy->check()
arm_io_storage -> arm_io_storage : open_fip(spec)
activate arm_io_storage
arm_io_storage -> io_storage : io_dev_init(fip_dev_handle, FIP_IMAGE_ID)
ref over io_storage : dev_init() on fip device
arm_io_storage -> io_storage : io_open(fip_dev_handle, spec, &local_image_handle)
ref over io_storage : io_open() on fip device
arm_io_storage -> io_storage : io_close(local_image_handle)
ref over io_storage : io_close() on fip device
hnote over arm_io_storage
fip_dev_handle ready
end note
end opt
deactivate arm_io_storage
else image_id = FIP_IMAGE_ID
activate arm_io_storage
note over arm_io_storage
get FIP_IMAGE_ID policy:
- memmap_dev_handle
- open_memmap()
end note
opt policy->check()
arm_io_storage -> arm_io_storage : open_memmap(spec)
activate arm_io_storage
arm_io_storage -> io_storage : io_dev_init(memmap_dev_handle, NULL)
ref over io_storage : dev_init() on memmap device
arm_io_storage -> io_storage : io_open(memmap_dev_handle, spec, &local_image_handle)
ref over io_storage : io_open() on memmap device
arm_io_storage -> io_storage : io_close(local_image_handle)
ref over io_storage : io_close() on memmap device
hnote over arm_io_storage
memmap_dev_handle ready
end note
deactivate arm_io_storage
end opt
deactivate arm_io_storage
end alt
end group
@enduml
@startuml
participant arm_io_storage order 1
participant io_storage order 2
participant io_fip order 3
participant io_memmap order 4
-> arm_io_storage : arm_io_setup()
group io dev registration
arm_io_storage -> io_fip : register_io_dev_fip(&fip_dev_con)
io_fip -> io_storage : io_register_device(&dev_info_pool[])
note over io_storage
devices[dev_count] = (fip_)dev_info_pool
dev_count++
end note
arm_io_storage -> io_memmap : register_io_dev_memmap(&memmap_dev_con)
io_memmap -> io_storage : io_register_device(&memmap_dev_info)
note over io_storage
devices[dev_count] = memmap_dev_info
dev_count++
end note
arm_io_storage -> io_storage : io_dev_open(fip_dev_con, NULL, fip_dev_handle)
io_storage -> io_storage : dev_open(dev_con, dev_spec, handle)
activate io_storage
opt dev_open() on fip device
io_storage -> io_fip : fip_dev_open(dev_spec, dev_info)
note over io_fip
dev_info = one of the
"fip_dev_info" from
dev_info_pool[]
end note
end opt
deactivate io_storage
arm_io_storage -> io_storage : io_dev_open(memmap_dev_con, NULL, memmap_dev_handle)
io_storage -> io_storage : dev_open(dev_con, dev_spec, handle)
activate io_storage
opt dev_open() on memmap device
io_storage -> io_memmap : memmap_dev_open(dev_spec, dev_info)
note over io_memmap
dev_info = memmap_dev_info
end note
end opt
deactivate io_storage
end group
@enduml
@startuml
participant bl_common order 1
participant arm_io_storage order 2
participant io_storage order 3
== Platform Setup ==
bl1_main -> xxx_bl1_setup : bl1_platform_setup()
xxx_bl1_setup -> arm_io_storage : plat_arm_io_setup()
arm_io_storage -> arm_io_storage : arm_io_setup()
ref over arm_io_storage, io_storage : io device registration
== Get Image ==
bl1_main -> xxx_bl1_setup : bl1_plat_get_next_image_id()
bl1_main <-- xxx_bl1_setup : BL2_IMAGE_ID
bl1_main -> bl1_main : bl1_load_bl2()
activate bl1_main
bl1_main -> plat_bl1_common : bl1_plat_get_image_desc(BL2_IMAGE_ID)
bl1_main <-- plat_bl1_common : BL2_IMAGE_DESC
bl1_main -> plat_bl1_common : bl1_plat_handle_pre_image_load(BL2_IMAGE_ID)
bl1_main -> bl_common : load_auth_image(BL2_IMAGE_ID, image_info)
activate bl_common
bl_common -> bl_common : load_auth_image_internal(BL2_IMAGE_ID, image_info, is_parent_image)
activate bl_common
bl_common -> bl_common : load_image(BL2_IMAGE_ID, image_info)
activate bl_common
bl_common -> arm_io_storage : plat_get_image_source(BL2_IMAGE_ID, &dev_handle, &image_spec)
ref over arm_io_storage, io_storage : init and check device (BL2_IMAGE_ID)
bl_common <-- arm_io_storage : dev_handle
bl_common -> io_storage : io_open(dev_handle, image_spec, &image_handle)
ref over io_storage : io_open() on fip device
bl_common <-- io_storage : image_handle
bl_common -> io_storage : io_size(image_handle, &image_size)
ref over io_storage : io_size() on fip device
bl_common -> io_storage : io_read(image_handle, image_base, image_size, &bytes_read)
ref over io_storage : io_read() on fip device
bl_common -> io_storage : io_close(image_handle)
ref over io_storage : io_close() on fip device
bl_common -> io_storage : io_dev_close(dev_handle)
ref over io_storage : io_dev_close() on fip device
deactivate bl_common
deactivate bl_common
deactivate bl_common
== Prepare Next Image ==
bl1_main -> plat_bl1_common : bl1_plat_handle_post_image_load(BL2_IMAGE_ID)
deactivate bl1_main
== Jump to next Image ==
@enduml
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment