a3135f0a8a649b206b41e0d7ab120d23d0640c3a
[10.03/openwrt.git] / target / linux / octeon / patches-2.6.30 / 004-named_alloc_function.patch
1 The MGMT ethernet driver uses these new functions.
2
3 Signed-off-by: David Daney <ddaney@caviumnetworks.com>
4 ---
5  arch/mips/cavium-octeon/executive/cvmx-bootmem.c |  101 ++++++++++++++++++++++
6  arch/mips/include/asm/octeon/cvmx-bootmem.h      |   85 ++++++++++++++++++
7  2 files changed, 186 insertions(+), 0 deletions(-)
8
9 --- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
10 +++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
11 @@ -97,6 +97,32 @@ void *cvmx_bootmem_alloc(uint64_t size, 
12         return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
13  }
14  
15 +void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
16 +                                    uint64_t max_addr, uint64_t align,
17 +                                    char *name)
18 +{
19 +       int64_t addr;
20 +
21 +       addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr,
22 +                                                 align, name, 0);
23 +       if (addr >= 0)
24 +               return cvmx_phys_to_ptr(addr);
25 +       else
26 +               return NULL;
27 +}
28 +
29 +void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
30 +                                      char *name)
31 +{
32 +    return cvmx_bootmem_alloc_named_range(size, address, address + size,
33 +                                         0, name);
34 +}
35 +
36 +void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name)
37 +{
38 +    return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name);
39 +}
40 +
41  int cvmx_bootmem_free_named(char *name)
42  {
43         return cvmx_bootmem_phy_named_block_free(name, 0);
44 @@ -584,3 +610,78 @@ int cvmx_bootmem_phy_named_block_free(ch
45         cvmx_bootmem_unlock();
46         return named_block_ptr != NULL; /* 0 on failure, 1 on success */
47  }
48 +
49 +int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
50 +                                          uint64_t max_addr,
51 +                                          uint64_t alignment,
52 +                                          char *name,
53 +                                          uint32_t flags)
54 +{
55 +       int64_t addr_allocated;
56 +       struct cvmx_bootmem_named_block_desc *named_block_desc_ptr;
57 +
58 +#ifdef DEBUG
59 +       cvmx_dprintf("cvmx_bootmem_phy_named_block_alloc: size: 0x%llx, min: "
60 +                    "0x%llx, max: 0x%llx, align: 0x%llx, name: %s\n",
61 +                    (unsigned long long)size,
62 +                    (unsigned long long)min_addr,
63 +                    (unsigned long long)max_addr,
64 +                    (unsigned long long)alignment,
65 +                    name);
66 +#endif
67 +       if (cvmx_bootmem_desc->major_version != 3) {
68 +               cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
69 +                            "%d.%d at addr: %p\n",
70 +                            (int)cvmx_bootmem_desc->major_version,
71 +                            (int)cvmx_bootmem_desc->minor_version,
72 +                            cvmx_bootmem_desc);
73 +               return -1;
74 +       }
75 +
76 +       /*
77 +        * Take lock here, as name lookup/block alloc/name add need to
78 +        * be atomic.
79 +        */
80 +       if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
81 +               cvmx_spinlock_lock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
82 +
83 +       /* Get pointer to first available named block descriptor */
84 +       named_block_desc_ptr =
85 +               cvmx_bootmem_phy_named_block_find(NULL,
86 +                                                 flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
87 +
88 +       /*
89 +        * Check to see if name already in use, return error if name
90 +        * not available or no more room for blocks.
91 +        */
92 +       if (cvmx_bootmem_phy_named_block_find(name,
93 +                                             flags | CVMX_BOOTMEM_FLAG_NO_LOCKING) || !named_block_desc_ptr) {
94 +               if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
95 +                       cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
96 +               return -1;
97 +       }
98 +
99 +
100 +       /*
101 +        * Round size up to mult of minimum alignment bytes We need
102 +        * the actual size allocated to allow for blocks to be
103 +        * coallesced when they are freed.  The alloc routine does the
104 +        * same rounding up on all allocations.
105 +        */
106 +       size = __ALIGN_MASK(size, (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1));
107 +
108 +       addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr,
109 +                                               alignment,
110 +                                               flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
111 +       if (addr_allocated >= 0) {
112 +               named_block_desc_ptr->base_addr = addr_allocated;
113 +               named_block_desc_ptr->size = size;
114 +               strncpy(named_block_desc_ptr->name, name,
115 +                       cvmx_bootmem_desc->named_block_name_len);
116 +               named_block_desc_ptr->name[cvmx_bootmem_desc->named_block_name_len - 1] = 0;
117 +       }
118 +
119 +       if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
120 +               cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
121 +       return addr_allocated;
122 +}
123 --- a/arch/mips/include/asm/octeon/cvmx-bootmem.h
124 +++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
125 @@ -183,6 +183,64 @@ extern void *cvmx_bootmem_alloc_range(ui
126   * Returns 0 on failure,
127   *         !0 on success
128   */
129 +
130 +
131 +/**
132 + * Allocate a block of memory from the free list that was passed
133 + * to the application by the bootloader, and assign it a name in the
134 + * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
135 + * Named blocks can later be freed.
136 + *
137 + * @size:      Size in bytes of block to allocate
138 + * @alignment: Alignment required - must be power of 2
139 + * @name:      name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
140 + *
141 + * Returns a pointer to block of memory, NULL on error
142 + */
143 +extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment,
144 +                                     char *name);
145 +
146 +
147 +
148 +/**
149 + * Allocate a block of memory from the free list that was passed
150 + * to the application by the bootloader, and assign it a name in the
151 + * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
152 + * Named blocks can later be freed.
153 + *
154 + * @size:     Size in bytes of block to allocate
155 + * @address:  Physical address to allocate memory at.  If this
156 + *            memory is not available, the allocation fails.
157 + * @name:     name of block - must be less than CVMX_BOOTMEM_NAME_LEN
158 + *            bytes
159 + *
160 + * Returns a pointer to block of memory, NULL on error
161 + */
162 +extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
163 +                                             char *name);
164 +
165 +
166 +
167 +/**
168 + * Allocate a block of memory from a specific range of the free list
169 + * that was passed to the application by the bootloader, and assign it
170 + * a name in the global named block table.  (part of the
171 + * cvmx_bootmem_descriptor_t structure) Named blocks can later be
172 + * freed.  If request cannot be satisfied within the address range
173 + * specified, NULL is returned
174 + *
175 + * @size:      Size in bytes of block to allocate
176 + * @min_addr:  minimum address of range
177 + * @max_addr:  maximum address of range
178 + * @align:     Alignment of memory to be allocated. (must be a power of 2)
179 + * @name:      name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
180 + *
181 + * Returns a pointer to block of memory, NULL on error
182 + */
183 +extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
184 +                                           uint64_t max_addr, uint64_t align,
185 +                                           char *name);
186 +
187  extern int cvmx_bootmem_free_named(char *name);
188  
189  /**
190 @@ -224,6 +282,33 @@ int64_t cvmx_bootmem_phy_alloc(uint64_t 
191                                uint32_t flags);
192  
193  /**
194 + * Allocates a named block of physical memory from the free list, at
195 + * (optional) requested address and alignment.
196 + *
197 + * @param size      size of region to allocate.  All requests are rounded
198 + *                  up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE
199 + *                  bytes size
200 + * @param min_addr Minimum address that block can occupy.
201 + * @param max_addr  Specifies the maximum address_min (inclusive) that
202 + *                  the allocation can use.
203 + * @param alignment Requested alignment of the block.  If this
204 + *                  alignment cannot be met, the allocation fails.
205 + *                  This must be a power of 2.  (Note: Alignment of
206 + *                  CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
207 + *                  internally enforced.  Requested alignments of less
208 + *                  than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
209 + *                  CVMX_BOOTMEM_ALIGNMENT_SIZE.)
210 + * @param name      name to assign to named block
211 + * @param flags     Flags to control options for the allocation.
212 + *
213 + * @return physical address of block allocated, or -1 on failure
214 + */
215 +int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
216 +                                          uint64_t max_addr,
217 +                                          uint64_t alignment,
218 +                                          char *name, uint32_t flags);
219 +
220 +/**
221   * Finds a named memory block by name.
222   * Also used for finding an unused entry in the named block table.
223   *