doc: Complete the storage abstraction layer doc

Add uml sequence and class diagram to illustrate the behavior of the
storage abstraction layer.

Change-Id: I338262729f8034cc3d3eea1d0ce19cca973a91bb
Signed-off-by: Louis Mayencourt <louis.mayencourt@arm.com>
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 72865a5..b327f6e 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2762,14 +2762,12 @@
 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 @@
 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.
 
+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 Storage layer provides mechanisms to initialize storage devices before
-IO operations are called. The basic operations supported by the layer
+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
diff --git a/docs/resources/diagrams/plantuml/io_arm_class_diagram.puml b/docs/resources/diagrams/plantuml/io_arm_class_diagram.puml
new file mode 100644
index 0000000..53594c2
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/io_arm_class_diagram.puml
@@ -0,0 +1,109 @@
+@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
diff --git a/docs/resources/diagrams/plantuml/io_dev_init_and_check.puml b/docs/resources/diagrams/plantuml/io_dev_init_and_check.puml
new file mode 100644
index 0000000..2752b33
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/io_dev_init_and_check.puml
@@ -0,0 +1,62 @@
+@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
diff --git a/docs/resources/diagrams/plantuml/io_dev_registration.puml b/docs/resources/diagrams/plantuml/io_dev_registration.puml
new file mode 100644
index 0000000..114c3b7
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/io_dev_registration.puml
@@ -0,0 +1,52 @@
+@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
diff --git a/docs/resources/diagrams/plantuml/io_framework_usage_overview.puml b/docs/resources/diagrams/plantuml/io_framework_usage_overview.puml
new file mode 100644
index 0000000..eb3e2b4
--- /dev/null
+++ b/docs/resources/diagrams/plantuml/io_framework_usage_overview.puml
@@ -0,0 +1,59 @@
+@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