paddr_t acpi_find_table(unsigned table_name, unsigned *lenp) { static unsigned num_tbls = -1; static paddr_t *tbl_array; paddr_t tbl_paddr; acpi_rsdp *root; acpi_generic *tbl; unsigned i; unsigned sig; if(num_tbls == 0) return NULL_PADDR; if(tbl_array == NULL) { root = board_find_acpi_rsdp(); if(root == NULL) { num_tbls = 0; return NULL_PADDR; } if(root->v1.Revision == ACPI_RSDP_REVISION_1_0) { tbl_paddr = root->v1.RsdtAddress; startup_memory_unmap(root); tbl = startup_memory_map(0x4096, tbl_paddr, PROT_READ); num_tbls = (tbl->hdr.Length - offsetof(acpi_rsdt, Entry)) / sizeof(tbl->rsdt.Entry[0]); tbl_array = ws_alloc(num_tbls * sizeof(*tbl_array)); for(i = 0; i < num_tbls; ++i) { tbl_array[i] = tbl->rsdt.Entry[i]; } } else { tbl_paddr = root->XsdtAddress; startup_memory_unmap(root); tbl = startup_memory_map(0x4096, tbl_paddr, PROT_READ); num_tbls = (tbl->hdr.Length - offsetof(acpi_xsdt, Entry)) / sizeof(tbl->xsdt.Entry[0]); tbl_array = ws_alloc(num_tbls * sizeof(*tbl_array)); for(i = 0; i < num_tbls; ++i) { tbl_array[i] = tbl->xsdt.Entry[i]; } } startup_memory_unmap(tbl); } for(i = 0; i < num_tbls; ++i) { tbl_paddr = tbl_array[i]; tbl = startup_memory_map(sizeof(*tbl), tbl_paddr, PROT_READ); sig = tbl->hdr.Signature; if(lenp != NULL) *lenp = tbl->hdr.Length; startup_memory_unmap(tbl); if(sig == table_name) return tbl_paddr; } return NULL_PADDR; }
void uncompress(int type, paddr32_t dst_paddr, paddr32_t src_paddr) { uint8_t *dst; uint8_t *src; // We assume that the destination is in the one-to-one mapping area. dst = MAKE_1TO1_PTR(dst_paddr); src = startup_memory_map(shdr->stored_size - shdr->startup_size, src_paddr, PROT_READ); switch(type) { #if SUPPORT_CMP_ZLIB case STARTUP_HDR_FLAGS1_COMPRESS_ZLIB: uncompress_zlib(dst, 0, src, 0, (uint8_t *)shdr->image_paddr + shdr->startup_size + shdr->imagefs_size); break; #endif #if SUPPORT_CMP_LZO case STARTUP_HDR_FLAGS1_COMPRESS_LZO: uncompress_lzo(dst, src); break; #endif #if SUPPORT_CMP_UCL case STARTUP_HDR_FLAGS1_COMPRESS_UCL: uncompress_ucl(dst, src); break; #endif default: crash("unsupported compression type"); } startup_memory_unmap(src); }
Elf32_Phdr * is_elf(Elf32_Ehdr *hdr, paddr32_t addr) { Elf32_Ehdr *p; p = startup_memory_map(sizeof(*hdr), addr, PROT_READ); *hdr = *p; startup_memory_unmap(p); if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) || hdr->e_ident [EI_DATA] != ELFDATANATIVE || hdr->e_machine != EM_NATIVE || hdr->e_phnum == 0 || hdr->e_phentsize != sizeof(Elf32_Phdr)) return(NULL); return startup_memory_map(hdr->e_phnum * sizeof(Elf32_Phdr), addr + hdr->e_phoff, PROT_READ|PROT_WRITE); }
void jtag_store_syspage_addr(void) { // Save the address of the system page at a known location to be // read by a JTAG. // Only save the system page address if some memory has been reserved if(jtag_syspage_address != NULL_PADDR) { paddr32_t *p; p = startup_memory_map(sizeof(syspage_paddr), jtag_syspage_address, PROT_READ|PROT_WRITE); *p = syspage_paddr; startup_memory_unmap(p); } }
void jtag_reserve_memory(paddr_t resmem_addr, size_t resmem_size, uint8_t resmem_flag) { void *p; // Reserve user specified block of memory alloc_ram(resmem_addr, resmem_size, 1); p = startup_memory_map(resmem_size, resmem_addr, PROT_READ|PROT_WRITE); // Determine if reserved memory should be cleared if(!resmem_flag) { memset(p, 0, resmem_size); } startup_memory_unmap(p); }
void copy_memory(paddr32_t dst, paddr32_t src, size_t len) { uint8_t *d; uint8_t *s; unsigned max; unsigned amount; max = (lsp.mdriver.size > 0) ? mdriver_max : len; for( ;; ) { mdriver_check(); amount = (len > max) ? max : len; // We make the assumption that the destination is going to // be in the one-to-one mapping area. d = MAKE_1TO1_PTR(dst); s = startup_memory_map(amount, src, PROT_READ); memmove(d, s, amount); startup_memory_unmap(s); len -= amount; if(len == 0) break; src += amount; dst += amount; } }