|
| 1 | + |
| 2 | +== Buffer Management Unit (BMU) ==[pfe_bmu] |
| 3 | + |
| 4 | +The buffer management unit (BMU) manages a buffer pool, allowing multiple |
| 5 | +peripherals to acquire and release buffers from the pool. |
| 6 | + |
| 7 | +The base address of the buffer pool is configurable, as well as the buffer |
| 8 | +size. The number of buffers in the pool is configurable too, to a limit of |
| 9 | +65535 buffers. |
| 10 | + |
| 11 | +The BMU does not perform any DMA transfers; the state of the buffer pool is |
| 12 | +kept in an internal memory which can be cleared by a software reset. |
| 13 | + |
| 14 | +The BMU can generate interrupt requests to notify a PE of buffer pool state |
| 15 | +changes. |
| 16 | + |
| 17 | +When a peripheral needs a buffer, it can allocate one by reading the |
| 18 | +BMU_ALLOC_CTRL register. If a buffer is available, its address will be returned |
| 19 | +and the BMU will mark this buffer as allocated. If no buffer is available, the |
| 20 | +address 0 will be returned. |
| 21 | + |
| 22 | +To free a previously allocated buffer, the peripheral must write the buffer |
| 23 | +address into the BMU_FREE_CTRL register. If the peripheral attempts to double |
| 24 | +free a buffer, the address of the offending free operation will be stored in |
| 25 | +the BMU_FREE_ERR_ADDR register. |
| 26 | + |
| 27 | +=== BMU registers ===[pfe_bmu_regs] |
| 28 | + |
| 29 | +|| BMU instance | Base offset in CBUS || |
| 30 | +| BMU1 | 0x240000 | |
| 31 | +| BMU2 | 0x250000 | |
| 32 | + |
| 33 | +|| Symbol | Offset | Description || |
| 34 | +| [BMU_VERSION #pfe_bmu_reg_bmu_version] | 0x000 | BMU version register (reads 0x21 on my hardware) | |
| 35 | +| [BMU_CTRL #pfe_bmu_reg_bmu_ctrl] | 0x004 | BMU control register (enable/reset) | |
| 36 | +| [BMU_UCAST_CONFIG #pfe_bmu_reg_bmu_ucast_config] | 0x008 | Number of buffers in the pool | |
| 37 | +| [BMU_UCAST_BASE_ADDR #pfe_bmu_reg_bmu_ucast_base_addr] | 0x00c | Base address to the buffer pool | |
| 38 | +| [BMU_BUF_SIZE #pfe_bmu_reg_bmu_buf_size] | 0x010 | Size of one buffer in the pool | |
| 39 | +| [BMU_BUF_CNT #pfe_bmu_reg_bmu_buf_cnt] | 0x014 | Not implemented? Always reads 0 and writes have no visible effect. | |
| 40 | +| [BMU_THRES #pfe_bmu_reg_bmu_thres] | 0x018 | BMU buffer count threshold | |
| 41 | +| [BMU_INT_SRC #pfe_bmu_reg_bmu_int_src] | 0x020 | BMU interrupt source register | |
| 42 | +| [BMU_INT_ENABLE #pfe_bmu_reg_bmu_int_enable] | 0x024 | BMU interrupt enable register | |
| 43 | +| [BMU_ALLOC_CTRL #pfe_bmu_reg_bmu_alloc_ctrl] | 0x030 | Allocates one buffer from the pool | |
| 44 | +| [BMU_FREE_CTRL #pfe_bmu_reg_bmu_free_ctrl] | 0x034 | Free one previously allocated buffer from the pool | |
| 45 | +| [BMU_FREE_ERR_ADDR #pfe_bmu_reg_bmu_free_err_addr] | 0x038 | Address of buffer used in invalid free operation | |
| 46 | +| [BMU_CURR_BUF_CNT #pfe_bmu_reg_bmu_curr_buf_cnt] | 0x03c | Number of buffers currently allocated | |
| 47 | +| [BMU_MCAST_CNT #pfe_bmu_reg_bmu_mcast_cnt] | 0x040 | Unknown | |
| 48 | +| [BMU_MCAST_ALLOC_CTRL #pfe_bmu_reg_bmu_mcast_alloc_ctrl] | 0x044 | Unknown | |
| 49 | +| [BMU_REM_BUF_CNT #pfe_bmu_reg_bmu_rem_buf_cnt] | 0x048 | Number of remaining free buffers in the pool | |
| 50 | +| [BMU_LOW_WATERMARK #pfe_bmu_reg_bmu_low_watermark] | 0x050 | Low watermark value | |
| 51 | +| [BMU_HIGH_WATERMARK #pfe_bmu_reg_bmu_high_watermark] | 0x054 | High watermark value | |
| 52 | +| [BMU_INT_MEM_ACCESS #pfe_bmu_reg_bmu_int_mem_access] | 0x100 | Internal memory access register | |
| 53 | + |
| 54 | +==== BMU_VERSION (BMU_BASE + 0x000) ====[pfe_bmu_reg_bmu_version] |
| 55 | + |
| 56 | +BMU silicon revision. 0x21 on my c2k chip. |
| 57 | + |
| 58 | +|| Symbol | Bit range | R/W | Description || |
| 59 | +| VERSION | ?-0 | R | BMU silicon revision | |
| 60 | + |
| 61 | +==== BMU_CTRL (BMU_BASE + 0x004) ====[pfe_bmu_reg_bmu_ctrl] |
| 62 | + |
| 63 | +BMU control register. The ENABLE bit must be set prior attempting to access |
| 64 | +the other BMU registers (except BMU_VERSION), otherwise the transaction may |
| 65 | +hang forever (or until the watchdog kicks in). |
| 66 | + |
| 67 | +Performing a software reset will not reset the value of the configuration |
| 68 | +registers, only the internal state will be cleared. |
| 69 | + |
| 70 | +|| Symbol | Bit range | R/W | Description || |
| 71 | +| SW_RESET | 1 | RW | Perform software reset. Self-clearing. | |
| 72 | +| ENABLE | 0 | RW | BMU enable. 0=disable 1=enable | |
| 73 | + |
| 74 | +==== BMU_UCAST_CONFIG (BMU_BASE + 0x008) ====[pfe_bmu_reg_bmu_ucast_config] |
| 75 | + |
| 76 | +Number of buffers in the pool. |
| 77 | + |
| 78 | +|| Symbol | Bit range | R/W | Description || |
| 79 | +| BUF_COUNT | 15-0 | RW | Total number of buffers in the pool. | |
| 80 | + |
| 81 | +==== BMU_UCAST_BASE_ADDR (BMU_BASE + 0x00c) ====[pfe_bmu_reg_bmu_ucast_base_addr] |
| 82 | + |
| 83 | +Base address of the buffer pool. |
| 84 | + |
| 85 | +The BASE_ADDRESS value is only used to convert between the buffer index, used |
| 86 | +internally, and the full physical address, used for the BMU_ALLOC_CTRL and |
| 87 | +BMU_FREE_CTRL registers. |
| 88 | + |
| 89 | +|| Symbol | Bit range | R/W | Description || |
| 90 | +| BASE_ADDRESS | 31-0 | RW | Base address of the buffer pool. | |
| 91 | + |
| 92 | +==== BMU_BUF_SIZE (BMU_BASE + 0x010) ====[pfe_bmu_reg_bmu_buf_size] |
| 93 | + |
| 94 | +Size of one buffer in the pool. |
| 95 | + |
| 96 | +The size in bytes is computed as follow: |
| 97 | + |
| 98 | +``` |
| 99 | +BUF_SIZE_BYTES = 1 << BUF_SIZE |
| 100 | +``` |
| 101 | + |
| 102 | +|| Symbol | Bit range | R/W | Description || |
| 103 | +| BUF_SIZE | 15-0 | RW | Buffer size in powers of 2 (the BUF_SIZE value from above formula). | |
| 104 | + |
| 105 | +==== BMU_BUF_CNT (BMU_BASE + 0x014) ====[pfe_bmu_reg_bmu_buf_cnt] |
| 106 | + |
| 107 | +Unknown. Always reads 0. Writes have no visible effect. |
| 108 | + |
| 109 | +==== BMU_THRES (BMU_BASE + 0x18) ====[pfe_bmu_reg_bmu_thres] |
| 110 | + |
| 111 | +Number of allocated buffer threshold at which an interrupt request should be |
| 112 | +generated. |
| 113 | + |
| 114 | +|| Symbol | Bit range | R/W | Description || |
| 115 | +| ? | 31-16 | RW | Purpose unknown. | |
| 116 | +| THRES | 15-0 | RW | An interrupt request is generated as long as the number of allocated buffer is greater or equal than THRES. | |
| 117 | + |
| 118 | +==== BMU_INT_SRC (BMU_BASE + 0x20) ====[pfe_bmu_reg_bmu_int_src] |
| 119 | + |
| 120 | +Interrupt source pending and acknowledge register. |
| 121 | + |
| 122 | +Reading from this register shows the pending interrupt requests. |
| 123 | + |
| 124 | +Writing into this registers acknowledges the interrupt requests which have |
| 125 | +their bit set in the value written. |
| 126 | + |
| 127 | +|| Symbol | Bit range | R/W | Description || |
| 128 | +| ? | 8 | RW | ? | |
| 129 | +| ? | 7 | RW | ? | |
| 130 | +| ? | 6 | RW | ? | |
| 131 | +| ? | 5 | RW | ? | |
| 132 | +| INVALID_FREE | 4 | RW | Set when freeing an already free buffer, or freeing a buffer outside the pool. | |
| 133 | +| THRES | 3 | RW | Set when the number of allocated buffers is greater or equal to the THRES value set in the BMU_THRES register. | |
| 134 | +| FULL | 2 | RW | Set when all buffers are allocated. | |
| 135 | +| EMPTY | 1 | RW | Set when no buffer is allocated. | |
| 136 | +| ? | 0 | RW | ? | |
| 137 | + |
| 138 | +==== BMU_INT_ENABLE (BMU_BASE + 0x24) ====[pfe_bmu_reg_bmu_int_enable] |
| 139 | + |
| 140 | +Interrupt source enable register. |
| 141 | + |
| 142 | +|| Symbol | Bit range | R/W | Description || |
| 143 | +| ? | 8 | RW | ? | |
| 144 | +| ? | 7 | RW | ? | |
| 145 | +| ? | 6 | RW | ? | |
| 146 | +| ? | 5 | RW | ? | |
| 147 | +| INVALID_FREE | 4 | RW | See description in BMU_INT_SRC. 0=disable 1=enable | |
| 148 | +| THRES | 3 | RW | See description in BMU_INT_SRC. 0=disable 1=enable | |
| 149 | +| FULL | 2 | RW | See description in BMU_INT_SRC. 0=disable 1=enable | |
| 150 | +| EMPTY | 1 | RW | See description in BMU_INT_SRC. 0=disable 1=enable | |
| 151 | +| ? | 0 | RW | ? | |
| 152 | + |
| 153 | +==== BMU_ALLOC_CTRL (BMU_BASE + 0x30) ====[pfe_bmu_reg_bmu_alloc_ctrl] |
| 154 | + |
| 155 | +Buffer allocation register. |
| 156 | + |
| 157 | +Reading from this register will allocate one buffer from the pool and return |
| 158 | +its address. If no free buffer is available, the value 0 is returned. |
| 159 | + |
| 160 | +|| Symbol | Bit range | R/W | Description || |
| 161 | +| BUF_ADDR | 31-0 | R | Address of the buffer just allocated. | |
| 162 | + |
| 163 | +==== BMU_FREE_CTRL (BMU_BASE + 0x34) ====[pfe_bmu_reg_bmu_free_ctrl] |
| 164 | + |
| 165 | +Buffer free register. |
| 166 | + |
| 167 | +Writing an address into this register will free the previously-allocated buffer |
| 168 | +with that address. |
| 169 | + |
| 170 | +If the address does not match any allocated buffer, an error will be reported |
| 171 | +via the INVALID_FREE interrupt source, and the offending address will be stored |
| 172 | +(at some point) in the BMU_FREE_ERR_ADDR register. |
| 173 | + |
| 174 | +|| Symbol | Bit range | R/W | Description || |
| 175 | +| BUF_ADDR | 31-0 | W | Address of the buffer to free. | |
| 176 | + |
| 177 | +==== BMU_FREE_ERR_ADDR (BMU_BASE + 0x38) ====[pfe_bmu_reg_bmu_free_err_addr] |
| 178 | + |
| 179 | +Buffer free error address register (buggy, see below). |
| 180 | + |
| 181 | +This register should contain the address which was last written into |
| 182 | +BMU_FREE_CTRL if that address was not a valid allocated buffer. |
| 183 | + |
| 184 | +It appears the hardware is buggy, and the correct value will not appear unless |
| 185 | +a few other invalid free attempts are made. |
| 186 | + |
| 187 | +|| Symbol | Bit range | R/W | Description || |
| 188 | +| BUF_ADDR | 31-0 | R | Address of the invalid buffer free attempt. | |
| 189 | + |
| 190 | +==== BMU_CURR_BUF_CNT (BMU_BASE + 0x3c) ====[pfe_bmu_reg_bmu_curr_buf_cnt] |
| 191 | + |
| 192 | +Number of buffers currently allocated. |
| 193 | + |
| 194 | +|| Symbol | Bit range | R/W | Description || |
| 195 | +| BUF_CNT | 15-0 | R | Number of allocated buffers. | |
| 196 | + |
| 197 | +==== BMU_MCAST_CNT (BMU_BASE + 0x40) ====[pfe_bmu_reg_bmu_mcast_cnt] |
| 198 | + |
| 199 | +Purpose unknown. |
| 200 | + |
| 201 | +|| Symbol | Bit range | R/W | Description || |
| 202 | +| ? | 2-0 | RW | Unknown | |
| 203 | + |
| 204 | +==== BMU_MCAST_ALLOC_CTRL (BMU_BASE + 0x44) ====[pfe_bmu_reg_bmu_mcast_alloc_ctrl] |
| 205 | + |
| 206 | +Purpose unknown. |
| 207 | + |
| 208 | +|| Symbol | Bit range | R/W | Description || |
| 209 | +| ? | 31-0 | R | Unknown | |
| 210 | + |
| 211 | +==== BMU_REM_BUF_CNT (BMU_BASE + 0x48) ====[pfe_bmu_reg_bmu_rem_buf_cnt] |
| 212 | + |
| 213 | +Number of remaining free buffers in the pool. |
| 214 | + |
| 215 | +|| Symbol | Bit range | R/W | Description || |
| 216 | +| BUF_CNT | 15-0 | R | Number of free buffers. | |
| 217 | + |
| 218 | +==== BMU_LOW_WATERMARK (BMU_BASE + 0x50) ====[pfe_bmu_reg_bmu_low_watermark] |
| 219 | + |
| 220 | +Purpose unknown. |
| 221 | + |
| 222 | +|| Symbol | Bit range | R/W | Description || |
| 223 | +| ? | 15-0 | RW | Unknown. Default value: 0x0000 | |
| 224 | + |
| 225 | +==== BMU_HIGH_WATERMARK (BMU_BASE + 0x54) ====[pfe_bmu_reg_bmu_high_watermark] |
| 226 | + |
| 227 | +Purpose unknown. |
| 228 | + |
| 229 | +|| Symbol | Bit range | R/W | Description || |
| 230 | +| ? | 15-0 | RW | Unknown. Default value: 0xffff | |
| 231 | + |
| 232 | +==== BMU_INT_MEM_ACCESS (BMU_BASE + 0x100) ====[pfe_bmu_reg_bmu_int_mem_access] |
| 233 | + |
| 234 | +Internal memory access register. |
| 235 | + |
| 236 | +|| Symbol | Bit range | R/W | Description || |
| 237 | +| ? | 31-0 | R | Unknown. Value changes as buffers are allocated/freed. | |
| 238 | + |
0 commit comments