169c410b8SPete Spreadborough /* SPDX-License-Identifier: BSD-3-Clause
2*e6e8f03eSRandy Schacher * Copyright(c) 2019-2023 Broadcom
369c410b8SPete Spreadborough * All rights reserved.
469c410b8SPete Spreadborough */
569c410b8SPete Spreadborough
669c410b8SPete Spreadborough #include <stdio.h>
769c410b8SPete Spreadborough #include <stdlib.h>
869c410b8SPete Spreadborough #include <stdbool.h>
969c410b8SPete Spreadborough #include <stdint.h>
1069c410b8SPete Spreadborough #include <errno.h>
1169c410b8SPete Spreadborough #include "stack.h"
1269c410b8SPete Spreadborough
1369c410b8SPete Spreadborough #define STACK_EMPTY -1
1469c410b8SPete Spreadborough
1569c410b8SPete Spreadborough /* Initialize stack
1669c410b8SPete Spreadborough */
1769c410b8SPete Spreadborough int
stack_init(int num_entries,uint32_t * items,struct stack * st)1869c410b8SPete Spreadborough stack_init(int num_entries, uint32_t *items, struct stack *st)
1969c410b8SPete Spreadborough {
2069c410b8SPete Spreadborough if (items == NULL || st == NULL)
2169c410b8SPete Spreadborough return -EINVAL;
2269c410b8SPete Spreadborough
2369c410b8SPete Spreadborough st->max = num_entries;
2469c410b8SPete Spreadborough st->top = STACK_EMPTY;
2569c410b8SPete Spreadborough st->items = items;
2669c410b8SPete Spreadborough
2769c410b8SPete Spreadborough return 0;
2869c410b8SPete Spreadborough }
2969c410b8SPete Spreadborough
30ae2ebb98SPeter Spreadborough /*
31ae2ebb98SPeter Spreadborough * Return the address of the items
32ae2ebb98SPeter Spreadborough */
stack_items(struct stack * st)33ae2ebb98SPeter Spreadborough uint32_t *stack_items(struct stack *st)
34ae2ebb98SPeter Spreadborough {
35ae2ebb98SPeter Spreadborough return st->items;
36ae2ebb98SPeter Spreadborough }
37ae2ebb98SPeter Spreadborough
3869c410b8SPete Spreadborough /* Return the size of the stack
3969c410b8SPete Spreadborough */
4069c410b8SPete Spreadborough int32_t
stack_size(struct stack * st)4169c410b8SPete Spreadborough stack_size(struct stack *st)
4269c410b8SPete Spreadborough {
4369c410b8SPete Spreadborough return st->top + 1;
4469c410b8SPete Spreadborough }
4569c410b8SPete Spreadborough
4669c410b8SPete Spreadborough /* Check if the stack is empty
4769c410b8SPete Spreadborough */
4869c410b8SPete Spreadborough bool
stack_is_empty(struct stack * st)4969c410b8SPete Spreadborough stack_is_empty(struct stack *st)
5069c410b8SPete Spreadborough {
5169c410b8SPete Spreadborough return st->top == STACK_EMPTY;
5269c410b8SPete Spreadborough }
5369c410b8SPete Spreadborough
5469c410b8SPete Spreadborough /* Check if the stack is full
5569c410b8SPete Spreadborough */
5669c410b8SPete Spreadborough bool
stack_is_full(struct stack * st)5769c410b8SPete Spreadborough stack_is_full(struct stack *st)
5869c410b8SPete Spreadborough {
5969c410b8SPete Spreadborough return st->top == st->max - 1;
6069c410b8SPete Spreadborough }
6169c410b8SPete Spreadborough
6269c410b8SPete Spreadborough /* Add element x to the stack
6369c410b8SPete Spreadborough */
6469c410b8SPete Spreadborough int
stack_push(struct stack * st,uint32_t x)6569c410b8SPete Spreadborough stack_push(struct stack *st, uint32_t x)
6669c410b8SPete Spreadborough {
6769c410b8SPete Spreadborough if (stack_is_full(st))
6869c410b8SPete Spreadborough return -EOVERFLOW;
6969c410b8SPete Spreadborough
7069c410b8SPete Spreadborough /* add an element and increments the top index
7169c410b8SPete Spreadborough */
7269c410b8SPete Spreadborough st->items[++st->top] = x;
7369c410b8SPete Spreadborough
7469c410b8SPete Spreadborough return 0;
7569c410b8SPete Spreadborough }
7669c410b8SPete Spreadborough
7769c410b8SPete Spreadborough /* Pop top element x from the stack and return
7869c410b8SPete Spreadborough * in user provided location.
7969c410b8SPete Spreadborough */
8069c410b8SPete Spreadborough int
stack_pop(struct stack * st,uint32_t * x)8169c410b8SPete Spreadborough stack_pop(struct stack *st, uint32_t *x)
8269c410b8SPete Spreadborough {
8369c410b8SPete Spreadborough if (stack_is_empty(st))
842ec9392bSAjit Khaparde return -ENOENT;
8569c410b8SPete Spreadborough
8669c410b8SPete Spreadborough *x = st->items[st->top];
8769c410b8SPete Spreadborough st->top--;
8869c410b8SPete Spreadborough
8969c410b8SPete Spreadborough return 0;
9069c410b8SPete Spreadborough }
9169c410b8SPete Spreadborough
9269c410b8SPete Spreadborough /* Dump the stack
9369c410b8SPete Spreadborough */
stack_dump(struct stack * st)9469c410b8SPete Spreadborough void stack_dump(struct stack *st)
9569c410b8SPete Spreadborough {
9669c410b8SPete Spreadborough int i, j;
9769c410b8SPete Spreadborough
9869c410b8SPete Spreadborough printf("top=%d\n", st->top);
9969c410b8SPete Spreadborough printf("max=%d\n", st->max);
10069c410b8SPete Spreadborough
10169c410b8SPete Spreadborough if (st->top == -1) {
10269c410b8SPete Spreadborough printf("stack is empty\n");
10369c410b8SPete Spreadborough return;
10469c410b8SPete Spreadborough }
10569c410b8SPete Spreadborough
10669c410b8SPete Spreadborough for (i = 0; i < st->max + 7 / 8; i++) {
10769c410b8SPete Spreadborough printf("item[%d] 0x%08x", i, st->items[i]);
10869c410b8SPete Spreadborough
10969c410b8SPete Spreadborough for (j = 0; j < 7; j++) {
11069c410b8SPete Spreadborough if (i++ < st->max - 1)
11169c410b8SPete Spreadborough printf(" 0x%08x", st->items[i]);
11269c410b8SPete Spreadborough }
11369c410b8SPete Spreadborough printf("\n");
11469c410b8SPete Spreadborough }
11569c410b8SPete Spreadborough }
116