blob: d4645c36e3b0ff82feada484e5389454ec91f41e [file] [log] [blame]
Achin Gupta4f6ad662013-10-25 09:08:21 +01001/*
Soby Mathewa0a897d2015-02-19 16:23:51 +00002 * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
Achin Gupta4f6ad662013-10-25 09:08:21 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta4f6ad662013-10-25 09:08:21 +01005 */
6
7#ifndef __BAKERY_LOCK_H__
8#define __BAKERY_LOCK_H__
9
Dan Handleyed6ff952014-05-14 17:44:19 +010010#include <platform_def.h>
Achin Gupta4f6ad662013-10-25 09:08:21 +010011
12#define BAKERY_LOCK_MAX_CPUS PLATFORM_CORE_COUNT
13
Soby Mathew523d6332015-01-08 18:02:19 +000014#ifndef __ASSEMBLY__
15#include <stdint.h>
16
Soby Mathewa0a897d2015-02-19 16:23:51 +000017/*****************************************************************************
18 * Internal helper macros used by the bakery lock implementation.
19 ****************************************************************************/
20/* Convert a ticket to priority */
21#define PRIORITY(t, pos) (((t) << 8) | (pos))
22
23#define CHOOSING_TICKET 0x1
24#define CHOSEN_TICKET 0x0
25
26#define bakery_is_choosing(info) (info & 0x1)
27#define bakery_ticket_number(info) ((info >> 1) & 0x7FFF)
28#define make_bakery_data(choosing, number) \
29 (((choosing & 0x1) | (number << 1)) & 0xFFFF)
30
31/*****************************************************************************
32 * External bakery lock interface.
33 ****************************************************************************/
Soby Mathew523d6332015-01-08 18:02:19 +000034#if USE_COHERENT_MEM
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010035/*
36 * Bakery locks are stored in coherent memory
37 *
38 * Each lock's data is contiguous and fully allocated by the compiler
39 */
Soby Mathew523d6332015-01-08 18:02:19 +000040
Dan Handleye2712bc2014-04-10 15:37:22 +010041typedef struct bakery_lock {
Soby Mathewa0a897d2015-02-19 16:23:51 +000042 /*
43 * The lock_data is a bit-field of 2 members:
44 * Bit[0] : choosing. This field is set when the CPU is
45 * choosing its bakery number.
46 * Bits[1 - 15] : number. This is the bakery number allocated.
47 */
48 volatile uint16_t lock_data[BAKERY_LOCK_MAX_CPUS];
Dan Handleye2712bc2014-04-10 15:37:22 +010049} bakery_lock_t;
Achin Gupta4f6ad662013-10-25 09:08:21 +010050
Soby Mathew523d6332015-01-08 18:02:19 +000051#else
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010052/*
53 * Bakery locks are stored in normal .bss memory
54 *
55 * Each lock's data is spread across multiple cache lines, one per CPU,
56 * but multiple locks can share the same cache line.
57 * The compiler will allocate enough memory for one CPU's bakery locks,
58 * the remaining cache lines are allocated by the linker script
59 */
Soby Mathew523d6332015-01-08 18:02:19 +000060
61typedef struct bakery_info {
62 /*
63 * The lock_data is a bit-field of 2 members:
64 * Bit[0] : choosing. This field is set when the CPU is
65 * choosing its bakery number.
66 * Bits[1 - 15] : number. This is the bakery number allocated.
67 */
68 volatile uint16_t lock_data;
69} bakery_info_t;
70
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010071typedef bakery_info_t bakery_lock_t;
Soby Mathew523d6332015-01-08 18:02:19 +000072
73#endif /* __USE_COHERENT_MEM__ */
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010074
Sandrine Bailleux37a12df2016-04-11 13:17:50 +010075static inline void bakery_lock_init(bakery_lock_t *bakery) {}
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010076void bakery_lock_get(bakery_lock_t *bakery);
77void bakery_lock_release(bakery_lock_t *bakery);
78
Soren Brinkmann46dd1702016-01-14 10:11:05 -080079#define DEFINE_BAKERY_LOCK(_name) bakery_lock_t _name __section("bakery_lock")
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010080
81#define DECLARE_BAKERY_LOCK(_name) extern bakery_lock_t _name
82
83
Soby Mathew523d6332015-01-08 18:02:19 +000084#endif /* __ASSEMBLY__ */
Achin Gupta4f6ad662013-10-25 09:08:21 +010085#endif /* __BAKERY_LOCK_H__ */