Fix a bug and stick nearer to the specification, introduce armv6_unified.
This commit is contained in:
parent
390df92f0b
commit
470038745c
1 changed files with 49 additions and 12 deletions
|
@ -2,10 +2,13 @@
|
||||||
#include <grub/cache.h>
|
#include <grub/cache.h>
|
||||||
#include <grub/arm/system.h>
|
#include <grub/arm/system.h>
|
||||||
|
|
||||||
|
/* This is only about cache architecture. It doesn't imply
|
||||||
|
the CPU architecture. */
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
ARCH_UNKNOWN,
|
ARCH_UNKNOWN,
|
||||||
ARCH_ARMV6,
|
ARCH_ARMV6,
|
||||||
|
ARCH_ARMV6_UNIFIED,
|
||||||
ARCH_ARMV7
|
ARCH_ARMV7
|
||||||
} type = ARCH_UNKNOWN;
|
} type = ARCH_UNKNOWN;
|
||||||
|
|
||||||
|
@ -23,7 +26,7 @@ probe_caches (void)
|
||||||
{
|
{
|
||||||
grub_uint32_t main_id, cache_type;
|
grub_uint32_t main_id, cache_type;
|
||||||
|
|
||||||
/* Read Cache Type Register */
|
/* Read main ID Register */
|
||||||
asm volatile ("mrc p15, 0, %0, c0, c0, 0": "=r"(main_id));
|
asm volatile ("mrc p15, 0, %0, c0, c0, 0": "=r"(main_id));
|
||||||
|
|
||||||
if (((main_id >> 12) & 0xf) == 0x0 || ((main_id >> 12) & 0xf) == 0x7
|
if (((main_id >> 12) & 0xf) == 0x0 || ((main_id >> 12) & 0xf) == 0x7
|
||||||
|
@ -33,17 +36,31 @@ probe_caches (void)
|
||||||
/* Read Cache Type Register */
|
/* Read Cache Type Register */
|
||||||
asm volatile ("mrc p15, 0, %0, c0, c0, 1": "=r"(cache_type));
|
asm volatile ("mrc p15, 0, %0, c0, c0, 1": "=r"(cache_type));
|
||||||
|
|
||||||
switch (cache_type >> 29)
|
switch (cache_type >> 24)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0x04:
|
||||||
|
case 0x0a:
|
||||||
|
case 0x0c:
|
||||||
|
case 0x0e:
|
||||||
|
case 0x1c:
|
||||||
|
grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3);
|
||||||
|
grub_arch_cache_ilinesz = 8 << (cache_type & 3);
|
||||||
|
type = ARCH_ARMV6_UNIFIED;
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
case 0x0b:
|
||||||
|
case 0x0d:
|
||||||
|
case 0x0f:
|
||||||
|
case 0x1d:
|
||||||
grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3);
|
grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3);
|
||||||
grub_arch_cache_ilinesz = 8 << (cache_type & 3);
|
grub_arch_cache_ilinesz = 8 << (cache_type & 3);
|
||||||
type = ARCH_ARMV6;
|
type = ARCH_ARMV6;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 0x80 ... 0x9f:
|
||||||
grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf);
|
grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf);
|
||||||
grub_arch_cache_ilinesz = 4 << (cache_type & 0xf);
|
grub_arch_cache_ilinesz = 4 << (cache_type & 0xf);
|
||||||
type = ARCH_ARMV7;
|
type = ARCH_ARMV7;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
grub_fatal ("Unsupported cache type 0x%x", cache_type);
|
grub_fatal ("Unsupported cache type 0x%x", cache_type);
|
||||||
}
|
}
|
||||||
|
@ -54,10 +71,21 @@ grub_arch_sync_caches (void *address, grub_size_t len)
|
||||||
{
|
{
|
||||||
if (type == ARCH_UNKNOWN)
|
if (type == ARCH_UNKNOWN)
|
||||||
probe_caches ();
|
probe_caches ();
|
||||||
if (type == ARCH_ARMV6)
|
switch (type)
|
||||||
grub_arch_sync_caches_armv6 (address, len);
|
{
|
||||||
if (type == ARCH_ARMV7)
|
case ARCH_ARMV6:
|
||||||
grub_arch_sync_caches_armv7 (address, len);
|
grub_arch_sync_caches_armv6 (address, len);
|
||||||
|
break;
|
||||||
|
case ARCH_ARMV7:
|
||||||
|
grub_arch_sync_caches_armv7 (address, len);
|
||||||
|
break;
|
||||||
|
/* Nothing to do. */
|
||||||
|
case ARCH_ARMV6_UNIFIED:
|
||||||
|
break;
|
||||||
|
/* Pacify GCC. */
|
||||||
|
case ARCH_UNKNOWN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -65,8 +93,17 @@ grub_arm_disable_caches_mmu (void)
|
||||||
{
|
{
|
||||||
if (type == ARCH_UNKNOWN)
|
if (type == ARCH_UNKNOWN)
|
||||||
probe_caches ();
|
probe_caches ();
|
||||||
if (type == ARCH_ARMV6)
|
switch (type)
|
||||||
grub_arm_disable_caches_mmu_armv6 ();
|
{
|
||||||
if (type == ARCH_ARMV7)
|
case ARCH_ARMV6_UNIFIED:
|
||||||
grub_arm_disable_caches_mmu_armv7 ();
|
case ARCH_ARMV6:
|
||||||
|
grub_arm_disable_caches_mmu_armv6 ();
|
||||||
|
break;
|
||||||
|
case ARCH_ARMV7:
|
||||||
|
grub_arm_disable_caches_mmu_armv7 ();
|
||||||
|
break;
|
||||||
|
/* Pacify GCC. */
|
||||||
|
case ARCH_UNKNOWN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue