blob: 1fece01afd1b36bda9f206a4fe25510293aca5ac [file] [log] [blame]
Achin Gupta4f6ad662013-10-25 09:08:21 +01001/*
Antonio Nino Diaz4b32e622018-08-16 16:52:57 +01002 * Copyright (c) 2013-2018, 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
Antonio Nino Diaz519248b2018-10-31 15:55:57 +00007#ifndef BAKERY_LOCK_H
8#define BAKERY_LOCK_H
Achin Gupta4f6ad662013-10-25 09:08:21 +01009
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
Julius Werner53456fc2019-07-09 13:49:11 -070014#ifndef __ASSEMBLER__
Antonio Nino Diaz4b32e622018-08-16 16:52:57 +010015#include <cdefs.h>
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000016#include <stdbool.h>
Soby Mathew523d6332015-01-08 18:02:19 +000017#include <stdint.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000018
19#include <lib/utils_def.h>
Soby Mathew523d6332015-01-08 18:02:19 +000020
Soby Mathewa0a897d2015-02-19 16:23:51 +000021/*****************************************************************************
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000022 * Internal helpers used by the bakery lock implementation.
Soby Mathewa0a897d2015-02-19 16:23:51 +000023 ****************************************************************************/
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000024
Soby Mathewa0a897d2015-02-19 16:23:51 +000025/* Convert a ticket to priority */
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000026static inline unsigned int bakery_get_priority(unsigned int t, unsigned int pos)
27{
28 return (t << 8) | pos;
29}
30
31#define CHOOSING_TICKET U(0x1)
32#define CHOSEN_TICKET U(0x0)
Soby Mathewa0a897d2015-02-19 16:23:51 +000033
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000034static inline bool bakery_is_choosing(unsigned int info)
35{
36 return (info & 1U) == CHOOSING_TICKET;
37}
Soby Mathewa0a897d2015-02-19 16:23:51 +000038
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000039static inline unsigned int bakery_ticket_number(unsigned int info)
40{
41 return (info >> 1) & 0x7FFFU;
42}
43
44static inline uint16_t make_bakery_data(unsigned int choosing, unsigned int num)
45{
46 unsigned int val = (choosing & 0x1U) | (num << 1);
47
48 return (uint16_t) val;
49}
Soby Mathewa0a897d2015-02-19 16:23:51 +000050
51/*****************************************************************************
52 * External bakery lock interface.
53 ****************************************************************************/
Soby Mathew523d6332015-01-08 18:02:19 +000054#if USE_COHERENT_MEM
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010055/*
56 * Bakery locks are stored in coherent memory
57 *
58 * Each lock's data is contiguous and fully allocated by the compiler
59 */
Soby Mathew523d6332015-01-08 18:02:19 +000060
Dan Handleye2712bc2014-04-10 15:37:22 +010061typedef struct bakery_lock {
Soby Mathewa0a897d2015-02-19 16:23:51 +000062 /*
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[BAKERY_LOCK_MAX_CPUS];
Dan Handleye2712bc2014-04-10 15:37:22 +010069} bakery_lock_t;
Achin Gupta4f6ad662013-10-25 09:08:21 +010070
Soby Mathew523d6332015-01-08 18:02:19 +000071#else
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010072/*
73 * Bakery locks are stored in normal .bss memory
74 *
75 * Each lock's data is spread across multiple cache lines, one per CPU,
76 * but multiple locks can share the same cache line.
77 * The compiler will allocate enough memory for one CPU's bakery locks,
78 * the remaining cache lines are allocated by the linker script
79 */
Soby Mathew523d6332015-01-08 18:02:19 +000080
81typedef struct bakery_info {
82 /*
83 * The lock_data is a bit-field of 2 members:
84 * Bit[0] : choosing. This field is set when the CPU is
85 * choosing its bakery number.
86 * Bits[1 - 15] : number. This is the bakery number allocated.
87 */
88 volatile uint16_t lock_data;
89} bakery_info_t;
90
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010091typedef bakery_info_t bakery_lock_t;
Soby Mathew523d6332015-01-08 18:02:19 +000092
93#endif /* __USE_COHERENT_MEM__ */
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010094
Sandrine Bailleux37a12df2016-04-11 13:17:50 +010095static inline void bakery_lock_init(bakery_lock_t *bakery) {}
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010096void bakery_lock_get(bakery_lock_t *bakery);
97void bakery_lock_release(bakery_lock_t *bakery);
98
Soren Brinkmann46dd1702016-01-14 10:11:05 -080099#define DEFINE_BAKERY_LOCK(_name) bakery_lock_t _name __section("bakery_lock")
Andrew Thoelkee466c9f2015-09-10 11:39:36 +0100100
101#define DECLARE_BAKERY_LOCK(_name) extern bakery_lock_t _name
102
103
Julius Werner53456fc2019-07-09 13:49:11 -0700104#endif /* __ASSEMBLER__ */
Antonio Nino Diaz519248b2018-10-31 15:55:57 +0000105#endif /* BAKERY_LOCK_H */