mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-15 09:04:17 +00:00
Merge pull request #761 from soby-mathew/sm/bakery_lock_fixes
Fix normal memory bakery lock implementation
This commit is contained in:
commit
c59428b150
1 changed files with 21 additions and 8 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -90,6 +90,22 @@ extern void *__PERCPU_BAKERY_LOCK_SIZE__;
|
|||
#define read_cache_op(addr, cached) if (cached) \
|
||||
dccivac((uintptr_t)addr)
|
||||
|
||||
/* Helper function to check if the lock is acquired */
|
||||
static inline int is_lock_acquired(const bakery_info_t *my_bakery_info,
|
||||
int is_cached)
|
||||
{
|
||||
/*
|
||||
* Even though lock data is updated only by the owning cpu and
|
||||
* appropriate cache maintenance operations are performed,
|
||||
* if the previous update was done when the cpu was not participating
|
||||
* in coherency, then there is a chance that cache maintenance
|
||||
* operations were not propagated to all the caches in the system.
|
||||
* Hence do a `read_cache_op()` prior to read.
|
||||
*/
|
||||
read_cache_op(my_bakery_info, is_cached);
|
||||
return !!(bakery_ticket_number(my_bakery_info->lock_data));
|
||||
}
|
||||
|
||||
static unsigned int bakery_get_ticket(bakery_lock_t *lock,
|
||||
unsigned int me, int is_cached)
|
||||
{
|
||||
|
@ -104,12 +120,8 @@ static unsigned int bakery_get_ticket(bakery_lock_t *lock,
|
|||
my_bakery_info = get_bakery_info(me, lock);
|
||||
assert(my_bakery_info);
|
||||
|
||||
/*
|
||||
* Prevent recursive acquisition.
|
||||
* Since lock data is written to and cleaned by the owning cpu, it
|
||||
* doesn't require any cache operations prior to reading the lock data.
|
||||
*/
|
||||
assert(!bakery_ticket_number(my_bakery_info->lock_data));
|
||||
/* Prevent recursive acquisition.*/
|
||||
assert(!is_lock_acquired(my_bakery_info, is_cached));
|
||||
|
||||
/*
|
||||
* Tell other contenders that we are through the bakery doorway i.e.
|
||||
|
@ -222,7 +234,8 @@ void bakery_lock_release(bakery_lock_t *lock)
|
|||
unsigned int is_cached = read_sctlr_el3() & SCTLR_C_BIT;
|
||||
|
||||
my_bakery_info = get_bakery_info(plat_my_core_pos(), lock);
|
||||
assert(bakery_ticket_number(my_bakery_info->lock_data));
|
||||
|
||||
assert(is_lock_acquired(my_bakery_info, is_cached));
|
||||
|
||||
my_bakery_info->lock_data = 0;
|
||||
write_cache_op(my_bakery_info, is_cached);
|
||||
|
|
Loading…
Add table
Reference in a new issue