1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** USBX Component                                                        */
16 /**                                                                       */
17 /**   USBX main stack                                                     */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /* Include necessary system files.  */
24 
25 #define UX_SOURCE_CODE
26 
27 #include "ux_api.h"
28 
29 
30 /**************************************************************************/
31 /*                                                                        */
32 /*  FUNCTION                                               RELEASE        */
33 /*                                                                        */
34 /*    _ux_utility_memory_byte_pool_create                 PORTABLE C      */
35 /*                                                           6.3.0        */
36 /*  AUTHOR                                                                */
37 /*                                                                        */
38 /*    Yajun Xia, Microsoft Corporation                                    */
39 /*                                                                        */
40 /*  DESCRIPTION                                                           */
41 /*                                                                        */
42 /*    This function creates a pool of memory bytes in the specified       */
43 /*    memory area.                                                        */
44 /*                                                                        */
45 /*  INPUT                                                                 */
46 /*                                                                        */
47 /*    pool_ptr                          Pointer to pool control block     */
48 /*    pool_start                        Address of beginning of pool area */
49 /*    pool_size                         Number of bytes in the byte pool  */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    UX_SUCCESS                        Successful completion status      */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    None                                                                */
58 /*                                                                        */
59 /*  CALLED BY                                                             */
60 /*                                                                        */
61 /*    USBX Components                                                     */
62 /*                                                                        */
63 /*  RELEASE HISTORY                                                       */
64 /*                                                                        */
65 /*    DATE              NAME                      DESCRIPTION             */
66 /*                                                                        */
67 /*  10-31-2023     Yajun Xia                Initial Version 6.3.0         */
68 /*                                                                        */
69 /**************************************************************************/
_ux_utility_memory_byte_pool_create(UX_MEMORY_BYTE_POOL * pool_ptr,VOID * pool_start,ULONG pool_size)70 UINT  _ux_utility_memory_byte_pool_create(UX_MEMORY_BYTE_POOL *pool_ptr, VOID *pool_start, ULONG pool_size)
71 {
72 
73 UCHAR               *block_ptr;
74 UCHAR               **block_indirect_ptr;
75 UCHAR               *temp_ptr;
76 ALIGN_TYPE          *free_ptr;
77 
78 
79     /* Initialize the byte pool control block to all zeros.  */
80     _ux_utility_memory_set((UCHAR *)pool_ptr, 0, sizeof(UX_MEMORY_BYTE_POOL)); /* Use case of memset is verified. */
81 
82     /* Round the pool size down to something that is evenly divisible by
83        an ULONG.  */
84     pool_size =   (pool_size/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
85 
86     /* Save the start and size of the pool.  */
87     pool_ptr -> ux_byte_pool_start =   UX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
88     pool_ptr -> ux_byte_pool_size =    pool_size;
89     pool_ptr -> ux_byte_pool_search =  UX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
90 
91     /* Initially, the pool will have two blocks.  One large block at the
92        beginning that is available and a small allocated block at the end
93        of the pool that is there just for the algorithm.  Be sure to count
94        the available block's header in the available bytes count.  */
95     pool_ptr -> ux_byte_pool_available =   pool_size - ((sizeof(VOID *)) + (sizeof(ALIGN_TYPE)));
96     pool_ptr -> ux_byte_pool_fragments =   ((UINT) 2);
97 
98     /* Each block contains a "next" pointer that points to the next block in the pool followed by a ALIGN_TYPE
99        field that contains either the constant UX_BYTE_BLOCK_FREE (if the block is free) or a pointer to the
100        owning pool (if the block is allocated).  */
101 
102     /* Calculate the end of the pool's memory area.  */
103     block_ptr =  UX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
104     block_ptr =  UX_UCHAR_POINTER_ADD(block_ptr, pool_size);
105 
106     /* Backup the end of the pool pointer and build the pre-allocated block.  */
107     block_ptr =  UX_UCHAR_POINTER_SUB(block_ptr, (sizeof(ALIGN_TYPE)));
108 
109     /* Cast the pool pointer into a ULONG.  */
110     temp_ptr =             UX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
111     block_indirect_ptr =   UX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
112     *block_indirect_ptr =  temp_ptr;
113 
114     block_ptr =            UX_UCHAR_POINTER_SUB(block_ptr, (sizeof(UCHAR *)));
115     block_indirect_ptr =   UX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
116     *block_indirect_ptr =  UX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
117 
118     /* Now setup the large available block in the pool.  */
119     temp_ptr =             UX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
120     block_indirect_ptr =   UX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(temp_ptr);
121     *block_indirect_ptr =  block_ptr;
122     block_ptr =            UX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
123     block_ptr =            UX_UCHAR_POINTER_ADD(block_ptr, (sizeof(UCHAR *)));
124     free_ptr =             UX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(block_ptr);
125     *free_ptr =            UX_BYTE_BLOCK_FREE;
126 
127     /* Return UX_SUCCESS.  */
128     return(UX_SUCCESS);
129 }
130