* Called for armv[45]. */
| 186 | * Called for armv[45]. |
| 187 | */ |
| 188 | static vm_offset_t |
| 189 | linux_parse_boot_param(struct arm_boot_params *abp) |
| 190 | { |
| 191 | struct arm_lbabi_tag *walker; |
| 192 | uint32_t revision; |
| 193 | uint64_t serial; |
| 194 | int size; |
| 195 | vm_offset_t lastaddr; |
| 196 | #ifdef FDT |
| 197 | struct fdt_header *dtb_ptr; |
| 198 | uint32_t dtb_size; |
| 199 | #endif |
| 200 | |
| 201 | /* |
| 202 | * Linux boot ABI: r0 = 0, r1 is the board type (!= 0) and r2 |
| 203 | * is atags or dtb pointer. If all of these aren't satisfied, |
| 204 | * then punt. Unfortunately, it looks like DT enabled kernels |
| 205 | * doesn't uses board type and U-Boot delivers 0 in r1 for them. |
| 206 | */ |
| 207 | if (abp->abp_r0 != 0 || abp->abp_r2 == 0) |
| 208 | return (0); |
| 209 | #ifdef FDT |
| 210 | /* Test if r2 point to valid DTB. */ |
| 211 | dtb_ptr = (struct fdt_header *)abp->abp_r2; |
| 212 | if (fdt_check_header(dtb_ptr) == 0) { |
| 213 | dtb_size = fdt_totalsize(dtb_ptr); |
| 214 | return (fake_preload_metadata(abp, dtb_ptr, dtb_size)); |
| 215 | } |
| 216 | #endif |
| 217 | |
| 218 | board_id = abp->abp_r1; |
| 219 | walker = (struct arm_lbabi_tag *)abp->abp_r2; |
| 220 | |
| 221 | if (ATAG_TAG(walker) != ATAG_CORE) |
| 222 | return 0; |
| 223 | |
| 224 | atag_list = walker; |
| 225 | while (ATAG_TAG(walker) != ATAG_NONE) { |
| 226 | switch (ATAG_TAG(walker)) { |
| 227 | case ATAG_CORE: |
| 228 | break; |
| 229 | case ATAG_MEM: |
| 230 | physmem_hardware_region(walker->u.tag_mem.start, |
| 231 | walker->u.tag_mem.size); |
| 232 | break; |
| 233 | case ATAG_INITRD2: |
| 234 | break; |
| 235 | case ATAG_SERIAL: |
| 236 | serial = walker->u.tag_sn.high; |
| 237 | serial <<= 32; |
| 238 | serial |= walker->u.tag_sn.low; |
| 239 | board_set_serial(serial); |
| 240 | break; |
| 241 | case ATAG_REVISION: |
| 242 | revision = walker->u.tag_rev.rev; |
| 243 | board_set_revision(revision); |
| 244 | break; |
| 245 | case ATAG_CMDLINE: |
no test coverage detected