Exemplo n.º 1
0
int c0_compare_int_usable(void)
{
    unsigned int delta;
    unsigned int cnt;

#ifdef CONFIG_KVM_GUEST
    return 1;
#endif

    /*
     * IP7 already pending?	 Try to clear it by acking the timer.
     */
    if (c0_compare_int_pending()) {
        cnt = read_c0_count();
        write_c0_compare(cnt);
        back_to_back_c0_hazard();
        while (read_c0_count() < (cnt  + COMPARE_INT_SEEN_TICKS))
            if (!c0_compare_int_pending())
                break;
        if (c0_compare_int_pending())
            return 0;
    }

    for (delta = 0x10; delta <= 0x400000; delta <<= 1) {
        cnt = read_c0_count();
        cnt += delta;
        write_c0_compare(cnt);
        back_to_back_c0_hazard();
        if ((int)(read_c0_count() - cnt) < 0)
            break;
        /* increase delta if the timer was already expired */
    }

    while ((int)(read_c0_count() - cnt) <= 0)
        ;	/* Wait for expiry  */

    while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
        if (c0_compare_int_pending())
            break;
    if (!c0_compare_int_pending())
        return 0;
    cnt = read_c0_count();
    write_c0_compare(cnt);
    back_to_back_c0_hazard();
    while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
        if (!c0_compare_int_pending())
            break;
    if (c0_compare_int_pending())
        return 0;

    /*
     * Feels like a real count / compare timer.
     */
    return 1;
}
Exemplo n.º 2
0
int c0_compare_int_usable(void)
{
	unsigned int delta;
	unsigned int cnt;

	/*
                                                              
  */
	if (c0_compare_int_pending()) {
		cnt = read_c0_count();
		write_c0_compare(cnt);
		back_to_back_c0_hazard();
		while (read_c0_count() < (cnt  + COMPARE_INT_SEEN_TICKS))
			if (!c0_compare_int_pending())
				break;
		if (c0_compare_int_pending())
			return 0;
	}

	for (delta = 0x10; delta <= 0x400000; delta <<= 1) {
		cnt = read_c0_count();
		cnt += delta;
		write_c0_compare(cnt);
		back_to_back_c0_hazard();
		if ((int)(read_c0_count() - cnt) < 0)
		    break;
		/*                                                 */
	}

	while ((int)(read_c0_count() - cnt) <= 0)
		;	/*                  */

	while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
		if (c0_compare_int_pending())
			break;
	if (!c0_compare_int_pending())
		return 0;
	cnt = read_c0_count();
	write_c0_compare(cnt);
	back_to_back_c0_hazard();
	while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
		if (!c0_compare_int_pending())
			break;
	if (c0_compare_int_pending())
		return 0;

	/*
                                            
  */
	return 1;
}
Exemplo n.º 3
0
static void mips_cpu_irq_disable(unsigned int irq)
{
	unsigned long flags;

	local_irq_save(flags);
	mask_mips_irq(irq);
	back_to_back_c0_hazard();
	local_irq_restore(flags);
}
Exemplo n.º 4
0
IMPLEMENTATION [mips32]:

#include <cstring>
#include "mipsregs.h"
#include "panic.h"
#include "warn.h"

PRIVATE
static void
Utcb_init::validate_utcb()
{
  const Mword dummy = 0x12345678;
  Mword old_value = 0;
  Mword new_value = 0;

  // TODO may need to expand validate_utcb() to catch an exception but this
  // approach is sufficient for platforms which silently ignore the accesses.
  // Write the test such that the exception handler can skip the faulting access
  // and still detect a failure, or consider using _recover_jmpbuf.

  if ((int)Config::Warn_level >= Warning)
    printf("Verifying access to UTCB pointer... ");

  // Detect issues with accessing the UTCB pointer early on.
  old_value = read_c0_ddatalo();
  write_c0_ddatalo(dummy);
  back_to_back_c0_hazard();
  new_value = read_c0_ddatalo();
  write_c0_ddatalo(old_value);

  if (dummy != new_value)
    panic("UTCB pointer could not be stored in DDataLo register.\n"
          "Consider using another COP0 register available to your platform.\n");
  else if ((int)Config::Warn_level >= Warning)
    printf("UTCB pointer stored in DDataLo\n");
}

// XXXKYMA: Store the UTCB pointer in COP0-DDataLo Register.
// This can be set in kernel mode and read in user mode.
IMPLEMENT 
void
Utcb_init::init()
{
  validate_utcb();
}