1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <assert.h>
18 #include <interface/spi/spi.h>
19 #include <lib/spi/common/utils.h>
20 #include <lk/macros.h>
21 #include <uapi/err.h>
22 
translate_srv_err(uint32_t srv_err)23 int translate_srv_err(uint32_t srv_err) {
24     switch (srv_err) {
25     case SPI_SRV_NO_ERROR:
26         return NO_ERROR;
27     case SPI_SRV_ERR_BUSY:
28         return ERR_BUSY;
29     case SPI_SRV_ERR_INVALID_ARGS:
30         return ERR_INVALID_ARGS;
31     case SPI_SRV_ERR_NOT_SUPPORTED:
32         return ERR_NOT_SUPPORTED;
33     case SPI_SRV_ERR_NOT_IMPLEMENTED:
34         return ERR_NOT_IMPLEMENTED;
35     case SPI_SRV_ERR_TOO_BIG:
36         return ERR_TOO_BIG;
37     default:
38         return ERR_GENERIC;
39     }
40 }
41 
translate_lk_err(int rc)42 uint32_t translate_lk_err(int rc) {
43     switch (rc) {
44     case NO_ERROR:
45         return SPI_SRV_NO_ERROR;
46     case ERR_BUSY:
47         return SPI_SRV_ERR_BUSY;
48     case ERR_INVALID_ARGS:
49         return SPI_SRV_ERR_INVALID_ARGS;
50     case ERR_NOT_SUPPORTED:
51         return SPI_SRV_ERR_NOT_SUPPORTED;
52     case ERR_NOT_IMPLEMENTED:
53         return SPI_SRV_ERR_NOT_IMPLEMENTED;
54     case ERR_TOO_BIG:
55         return SPI_SRV_ERR_TOO_BIG;
56     default:
57         return SPI_SRV_ERR_GENERIC;
58     }
59 }
60 
mb_init(struct mem_buf * mb,void * buf,size_t sz,size_t align)61 void mb_init(struct mem_buf* mb, void* buf, size_t sz, size_t align) {
62     assert(align && IS_ALIGNED(buf, align));
63 
64     mb->buf = buf;
65     mb->capacity = sz;
66     mb->align = align;
67     mb->curr_size = 0;
68     mb->pos = 0;
69 }
70 
mb_destroy(struct mem_buf * mb)71 void mb_destroy(struct mem_buf* mb) {
72     mb->buf = NULL;
73     mb->capacity = 0;
74     mb->align = 0;
75     mb->curr_size = 0;
76     mb->pos = 0;
77 }
78 
mb_is_destroyed(struct mem_buf * mb)79 static inline bool mb_is_destroyed(struct mem_buf* mb) {
80     return !mb->buf;
81 }
82 
mb_resize(struct mem_buf * mb,size_t sz)83 bool mb_resize(struct mem_buf* mb, size_t sz) {
84     if (mb_is_destroyed(mb)) {
85         return false;
86     }
87     if (sz <= mb->capacity) {
88         mb->curr_size = sz;
89         mb->pos = 0;
90         return true;
91     }
92     return false;
93 }
94 
mb_advance_pos(struct mem_buf * mb,size_t sz)95 void* mb_advance_pos(struct mem_buf* mb, size_t sz) {
96     void* p;
97 
98     if (mb_is_destroyed(mb)) {
99         return NULL;
100     }
101 
102     assert(IS_ALIGNED(mb->pos, mb->align));
103     assert(mb->curr_size >= mb->pos);
104 
105     sz = round_up(sz, mb->align);
106 
107     if (sz > (mb->curr_size - mb->pos)) {
108         return NULL;
109     }
110 
111     p = (void*)(mb->buf + mb->pos);
112     mb->pos += sz;
113     assert(IS_ALIGNED(mb->pos, mb->align));
114     return p;
115 }
116