vxBoot/src/hardware/get_info.c

58 lines
1.4 KiB
C

#include "vxBoot/hardware.h"
#include <gint/mmu.h>
/* __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;
return;
}
}
}