#include "vxBoot/hardware.h" #include /* __ram_get_size() : try to determine the RAM size */ static ptrdiff_t __ram_get_size(uintptr_t start_ram) { volatile uint32_t *ptr = (void*)start_ram; volatile uint32_t *tst = (void*)start_ram; uint32_t backup; //TODO: use UTLB page size information to walk through each pages while (1) { ptr = &ptr[4096]; backup = ptr[0]; ptr[0] = 0xdeadbeef; if (ptr[0] != 0xdeadbeef || ptr[0] == tst[0]) break; ptr[0] = backup; } ptr[0] = backup; return ((ptrdiff_t)((uintptr_t)ptr - (uintptr_t)tst)); } /* hardware_get_info() : get hardware information */ int hardware_get_info(struct hwinfo * const hwinfo) { if (hwinfo == NULL) return (-1); uintptr_t uram = mmu_translate(0x08100000, NULL); hwinfo->ram.physical.origin_addr = uram & 0xff000000; hwinfo->ram.physical.kernel_addr = uram + mmu_uram_size(); hwinfo->ram.physical.user_addr = uram; hwinfo->ram.size = __ram_get_size(uram | 0xa0000000); hwinfo->ram.available = hwinfo->ram.size; hwinfo->ram.available -= hwinfo->ram.physical.kernel_addr & 0x00ffffff; return (0); } /* hardware_utlb_patch() : patch the UTLB NULL page set by Casio */ void hardware_utlb_patch(void) { for (int i = 0; i < 64; ++i) { utlb_addr_t *addr = (void*)utlb_addr(i); utlb_data_t *data = (void*)utlb_data(i); if(!addr->V || !data->V) continue; uintptr_t vaddr = addr->VPN << 10; if (vaddr == 0x00000000) { addr->V = 0; data->V = 0; __asm__ volatile ( "mov %0, r0;" "icbi @r0;" "nop" : : "r"(0xa0000000) : ); return; } } }