blob: 8e3748e18554ae9059e73f152537badb60952943 [file] [log] [blame]
Thomas Heijligen5c43abc2023-12-11 15:24:36 +00001package body FILO.Blockdev is
Thomas Heijligend1e04572023-11-27 14:28:55 +00002
3 procedure Read
Thomas Heijligen68ed36e2024-01-22 11:43:54 +00004 (Buffer : out Buffer_Type;
Nico Huber9c041872023-12-12 13:24:55 +01005 Offset : in Blockdev_Offset;
Thomas Heijligen62268ee2023-11-27 15:10:41 +00006 Success : out Boolean)
Nico Huber1f3825e2023-12-14 00:05:20 +01007 with
8 SPARK_Mode => Off
Thomas Heijligend1e04572023-11-27 14:28:55 +00009 is
Thomas Heijligena968f6f2023-12-11 09:40:06 +000010 use Interfaces.C;
11
Nico Huber7f613492023-12-12 13:32:06 +010012 Sector : constant unsigned_long := unsigned_long (Offset / BLOCK_SIZE);
13 Byte_Offset : constant unsigned_long := unsigned_long (Offset rem BLOCK_SIZE);
Thomas Heijligena968f6f2023-12-11 09:40:06 +000014 Byte_Len : constant unsigned_long := unsigned_long (Buffer'Length);
15 Buf : constant System.Address := Buffer'Address;
16
17 -- NOTE: C_devread returns 1 on success
18 function To_Success (Item : Interfaces.C.int) return Boolean is
19 (if Item = 1 then True else False);
20
Thomas Heijligend1e04572023-11-27 14:28:55 +000021 begin
Nico Hubera5296602023-12-12 13:30:31 +010022 -- With 32-bit longs, the current C interface
23 -- can't access more than 512 * 2 ** 32:
Nico Huber6fb38542024-01-26 23:53:17 +010024 pragma Warnings (GNAT, Off, "condition can only be True if");
25 pragma Warnings (GNAT, Off, "condition is always False");
Nico Huber22173222023-12-14 00:02:03 +010026 if Unsigned_64 (Offset / BLOCK_SIZE) > Unsigned_64 (unsigned_long'last) then
Nico Hubera5296602023-12-12 13:30:31 +010027 Success := False;
28 return;
29 end if;
Thomas Heijligena968f6f2023-12-11 09:40:06 +000030 Success := To_Success (C_devread (Sector, Byte_Offset, Byte_Len, Buf));
Thomas Heijligend1e04572023-11-27 14:28:55 +000031 end Read;
32
Thomas Heijligen5c43abc2023-12-11 15:24:36 +000033end FILO.Blockdev;