Skip to content

Commit e15bd39

Browse files
committed
Fix cache line alignment in Cache_Maintenance
The generic Cache_Maintenance procedure used the raw Start address as the initial DCCMVAC write address without first aligning it down to a cache line boundary. If Start was not 32-byte aligned, the first cache line was only partially cleaned. Additionally, Len was not extended to account for the trimmed prefix bytes, leaving the final partial cache line unflushed. Fix by aligning Op_Addr down to the nearest cache line boundary and extending Op_Size by the corresponding offset, ensuring all cache lines covering [Start, Start+Len) are cleaned. correct new copyright date formatting for readability
1 parent 68b8aa9 commit e15bd39

1 file changed

Lines changed: 9 additions & 9 deletions

File tree

arch/ARM/cortex_m/src/cache/cortex_m-cache.adb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
------------------------------------------------------------------------------
33
-- --
4-
-- Copyright (C) 2015-2016, AdaCore --
4+
-- Copyright (C) 2015-2026, AdaCore --
55
-- --
66
-- Redistribution and use in source and binary forms, with or without --
77
-- modification, are permitted provided that the following conditions are --
@@ -90,24 +90,24 @@ package body Cortex_M.Cache is
9090
if not D_Cache_Enabled then
9191
return;
9292
end if;
93-
9493
declare
9594
function To_U32 is new Ada.Unchecked_Conversion
9695
(System.Address, UInt32);
97-
98-
Op_Size : Integer_32 := Integer_32 (Len);
99-
Op_Addr : UInt32 := To_U32 (Start);
100-
Reg : UInt32 with Volatile, Address => Reg_Address;
101-
96+
Aligned_Addr : constant UInt32 := To_U32 (Start) and not (Data_Cache_Line_Size - 1);
97+
Aligned_Size : constant UInt32 := UInt32 (Len) + (To_U32 (Start) - Aligned_Addr);
98+
Op_Size : Integer_32 := Integer_32 (Aligned_Size);
99+
-- Op_Size is extended by the number of bytes trimmed from the start,
100+
-- ensuring the final partial line is covered
101+
Op_Addr : UInt32 := Aligned_Addr;
102+
-- Op_Addr starts at Start rounded down to the nearest cache line
103+
Reg : UInt32 with Volatile, Address => Reg_Address;
102104
begin
103105
DSB;
104-
105106
while Op_Size > 0 loop
106107
Reg := Op_Addr;
107108
Op_Addr := Op_Addr + Data_Cache_Line_Size;
108109
Op_Size := Op_Size - Integer_32 (Data_Cache_Line_Size);
109110
end loop;
110-
111111
DSB;
112112
ISB;
113113
end;

0 commit comments

Comments
 (0)