blob: 2d1612e17b43b19caad606481032b43a27ccc6f7 [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
Soby Mathew523d6332015-01-08 18:02:19 +000014#ifndef __ASSEMBLY__
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 Diaz519248b2018-10-31 15:55:57 +000018#include <utils_def.h>
Soby Mathew523d6332015-01-08 18:02:19 +000019
Soby Mathewa0a897d2015-02-19 16:23:51 +000020/*****************************************************************************
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000021 * Internal helpers used by the bakery lock implementation.
Soby Mathewa0a897d2015-02-19 16:23:51 +000022 ****************************************************************************/
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000023
Soby Mathewa0a897d2015-02-19 16:23:51 +000024/* Convert a ticket to priority */
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000025static inline unsigned int bakery_get_priority(unsigned int t, unsigned int pos)
26{
27 return (t << 8) | pos;
28}
29
30#define CHOOSING_TICKET U(0x1)
31#define CHOSEN_TICKET U(0x0)
Soby Mathewa0a897d2015-02-19 16:23:51 +000032
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000033static inline bool bakery_is_choosing(unsigned int info)
34{
35 return (info & 1U) == CHOOSING_TICKET;
36}
Soby Mathewa0a897d2015-02-19 16:23:51 +000037
Antonio Nino Diaz519248b2018-10-31 15:55:57 +000038static inline unsigned int bakery_ticket_number(unsigned int info)
39{
40 return (info >> 1) & 0x7FFFU;
41}
42
43static inline uint16_t make_bakery_data(unsigned int choosing, unsigned int num)
44{
45 unsigned int val = (choosing & 0x1U) | (num << 1);
46
47 return (uint16_t) val;
48}
Soby Mathewa0a897d2015-02-19 16:23:51 +000049
50/*****************************************************************************
51 * External bakery lock interface.
52 ****************************************************************************/
Soby Mathew523d6332015-01-08 18:02:19 +000053#if USE_COHERENT_MEM
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010054/*
55 * Bakery locks are stored in coherent memory
56 *
57 * Each lock's data is contiguous and fully allocated by the compiler
58 */
Soby Mathew523d6332015-01-08 18:02:19 +000059
Dan Handleye2712bc2014-04-10 15:37:22 +010060typedef struct bakery_lock {
Soby Mathewa0a897d2015-02-19 16:23:51 +000061 /*
62 * The lock_data is a bit-field of 2 members:
63 * Bit[0] : choosing. This field is set when the CPU is
64 * choosing its bakery number.
65 * Bits[1 - 15] : number. This is the bakery number allocated.
66 */
67 volatile uint16_t lock_data[BAKERY_LOCK_MAX_CPUS];
Dan Handleye2712bc2014-04-10 15:37:22 +010068} bakery_lock_t;
Achin Gupta4f6ad662013-10-25 09:08:21 +010069
Soby Mathew523d6332015-01-08 18:02:19 +000070#else
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010071/*
72 * Bakery locks are stored in normal .bss memory
73 *
74 * Each lock's data is spread across multiple cache lines, one per CPU,
75 * but multiple locks can share the same cache line.
76 * The compiler will allocate enough memory for one CPU's bakery locks,
77 * the remaining cache lines are allocated by the linker script
78 */
Soby Mathew523d6332015-01-08 18:02:19 +000079
80typedef struct bakery_info {
81 /*
82 * The lock_data is a bit-field of 2 members:
83 * Bit[0] : choosing. This field is set when the CPU is
84 * choosing its bakery number.
85 * Bits[1 - 15] : number. This is the bakery number allocated.
86 */
87 volatile uint16_t lock_data;
88} bakery_info_t;
89
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010090typedef bakery_info_t bakery_lock_t;
Soby Mathew523d6332015-01-08 18:02:19 +000091
92#endif /* __USE_COHERENT_MEM__ */
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010093
Sandrine Bailleux37a12df2016-04-11 13:17:50 +010094static inline void bakery_lock_init(bakery_lock_t *bakery) {}
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010095void bakery_lock_get(bakery_lock_t *bakery);
96void bakery_lock_release(bakery_lock_t *bakery);
97
Soren Brinkmann46dd1702016-01-14 10:11:05 -080098#define DEFINE_BAKERY_LOCK(_name) bakery_lock_t _name __section("bakery_lock")
Andrew Thoelkee466c9f2015-09-10 11:39:36 +010099
100#define DECLARE_BAKERY_LOCK(_name) extern bakery_lock_t _name
101
102
Soby Mathew523d6332015-01-08 18:02:19 +0000103#endif /* __ASSEMBLY__ */
Antonio Nino Diaz519248b2018-10-31 15:55:57 +0000104#endif /* BAKERY_LOCK_H */