コード例 #1
0
ファイル: kern_microtime.c プロジェクト: MarginC/kame
/*
 * This routine is called about once per second directly by the master
 * processor and via an interprocessor interrupt for other processors.
 * It determines the CC frequency of each processor relative to the
 * master clock and the time this determination is made.  These values
 * are used by microtime() to interpolate the microseconds between
 * timer interrupts.  Note that we assume the kernel variables have
 * been zeroed early in life.
 */
void
cc_microset(struct cpu_info *ci)
{
	struct timeval t;
	int64_t delta, denom;

	/* Note: Clock interrupts are already blocked. */

	denom = ci->ci_cc_cc;
	t = cc_microset_time;		/* XXXSMP: not atomic */
	ci->ci_cc_cc = cpu_counter32();

	if (ci->ci_cc_denom == 0) {
		/*
		 * This is our first time here on this CPU.  Just
		 * start with reasonable initial values.
		 */
		ci->ci_cc_time = t;
		ci->ci_cc_ms_delta = 1000000;
		ci->ci_cc_denom = cpu_frequency(ci);
		return;
	}

	denom = ci->ci_cc_cc - denom;
	if (denom < 0)
		denom += 0x100000000L;

	delta = (t.tv_sec - ci->ci_cc_time.tv_sec) * 1000000 +
	    (t.tv_usec - ci->ci_cc_time.tv_usec);

	ci->ci_cc_time = t;
	/*
	 * Make sure it's within .5 to 1.5 seconds -- otherwise,
	 * the time is probably be frobbed with by the timekeeper
	 * or the human.
	 */
	if (delta > 500000 && delta < 1500000) {
		ci->ci_cc_ms_delta = delta;
		ci->ci_cc_denom = denom;
#if 0
		printf("cc_microset: delta %" PRId64 ", denom %" PRId64 "\n",
		       delta, denom);
#endif
	} else {
#if 0
		printf("cc_microset: delta %" PRId64 ", resetting state\n",
		       delta);
#endif
		ci->ci_cc_ms_delta = 1000000;
		ci->ci_cc_denom = cpu_frequency(ci);
	}
}
コード例 #2
0
ファイル: clock.c プロジェクト: MarginC/kame
static uint64_t
get_tsc_offset_ns(void)
{
	uint32_t tsc_delta;
	struct cpu_info *ci = curcpu();

	tsc_delta = cpu_counter32() - shadow_tsc_stamp;
	return tsc_delta * 1000000000 / cpu_frequency(ci);
}
コード例 #3
0
ファイル: misc_lzma.c プロジェクト: janfj/dd-wrt
ulg
decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p)
{
    output_data = (uch *) output_start;
    free_mem_ptr = free_mem_ptr_p;
    free_mem_ptr_end = free_mem_ptr_end_p;
    disable_watchdog();
    arch_decomp_setup();
    /* initialize clock */
    HAL_CLOCK_INITIALIZE(RTC_PERIOD);
    printf("MicroRedBoot v1.4, (c) 2009 DD-WRT.COM (%s REVISION %s)\n", __DATE__,SVN_REVISION);
    printf("keep the reset button pushed to enter redboot!\n");
    printf("CPU Type: Atheros AR%s\n",get_system_type());
    printf("CPU Clock: %dMhz\n", cpu_frequency() / 1000000);
    nvram_init();
    char *ddboard = nvram_get("DD_BOARD");
    if (ddboard)
        printf("Board: %s\n", ddboard);
    char *resetbutton = nvram_get("resetbutton_enable");
    if (resetbutton && !strcmp(resetbutton, "0"))
        puts("reset button manual override detected! (nvram var resetbutton_enable=0)\n");
    if (resetTouched() || (resetbutton && !strcmp(resetbutton, "0"))) {
        puts("Reset Button triggered\nBooting Recovery RedBoot\n");

        int count = 5;
        while (count--) {
            if (!resetTouched())	// check if reset button is unpressed again
                break;
            udelay(1000000);
        }
        if (count <= 0) {
            puts("reset button 5 seconds pushed, erasing nvram\n");

            if (!flashdetect())
                flash_erase_nvram(flashsize, NVRAM_SPACE);
        }

        bootoffset = 0x800004bc;
        resettrigger = 0;
        puts("loading");
        lzma_unzip();
        puts("\n\n\n");
        return output_ptr;
    } else {
        flashdetect();
        linuxaddr = getLinux();
        puts("Booting Linux\n");
        resettrigger = 1;

        /* important, enable ethernet bus, if the following lines are not initialized linux will not be able to use the ethernet mac, taken from redboot source */
        enable_ethernet();
        puts("loading");
        lzma_unzip();
        set_cmdline();
    }
}
コード例 #4
0
ファイル: ipifuncs.c プロジェクト: ryo/netbsd-src
/*
 * Wait for IPI operation to complete.
 * Return 0 on success.
 */
int
sparc64_ipi_wait(sparc64_cpuset_t volatile *cpus_watchset, sparc64_cpuset_t cpus_mask)
{
	uint64_t limit = gettick() + cpu_frequency(curcpu());

	while (gettick() < limit) {
		membar_Sync();
		if (CPUSET_EQUAL(*cpus_watchset, cpus_mask))
			return 0;
	}
	return 1;
}
コード例 #5
0
ファイル: kern_cctr.c プロジェクト: ryo/netbsd-src
/*
 * pick up tick count scaled to reference tick count
 */
u_int
cc_get_timecount(struct timecounter *tc)
{
	struct cpu_info *ci;
	int64_t rcc, cc, ncsw;
	u_int gen;

 retry:
 	ncsw = curlwp->l_ncsw;
 	__insn_barrier();
	ci = curcpu();
	if (ci->ci_cc.cc_denom == 0) {
		/*
		 * This is our first time here on this CPU.  Just
		 * start with reasonable initial values.
		 */
	        ci->ci_cc.cc_cc    = cpu_counter32();
		ci->ci_cc.cc_val   = 0;
		if (ci->ci_cc.cc_gen == 0)
			ci->ci_cc.cc_gen++;

		ci->ci_cc.cc_denom = cpu_frequency(ci);
		if (ci->ci_cc.cc_denom == 0)
			ci->ci_cc.cc_denom = cc_timecounter.tc_frequency;
		ci->ci_cc.cc_delta = ci->ci_cc.cc_denom;
	}

	/*
	 * read counter and re-read when the re-calibration
	 * strikes inbetween
	 */
	do {
		/* pick up current generation number */
		gen = ci->ci_cc.cc_gen;

		/* determine local delta ticks */
		cc = cpu_counter32() - ci->ci_cc.cc_cc;
		if (cc < 0)
			cc += 0x100000000LL;

		/* scale to primary */
		rcc = (cc * ci->ci_cc.cc_delta) / ci->ci_cc.cc_denom
		    + ci->ci_cc.cc_val;
	} while (gen == 0 || gen != ci->ci_cc.cc_gen);
 	__insn_barrier();
 	if (ncsw != curlwp->l_ncsw) {
 		/* Was preempted */ 
 		goto retry;
	}

	return rcc;
}
コード例 #6
0
ファイル: kern_cctr.c プロジェクト: ryo/netbsd-src
/*
 * This routine is called about once per second directly by the master
 * processor and via an interprocessor interrupt for other processors.
 * It determines the CC frequency of each processor relative to the
 * master clock and the time this determination is made.  These values
 * are used by cc_get_timecount() to interpolate the ticks between
 * timer interrupts.  Note that we assume the kernel variables have
 * been zeroed early in life.
 */
void
cc_calibrate_cpu(struct cpu_info *ci)
{
	u_int   gen;
	int64_t val;
	int64_t delta, denom;
	int s;
#ifdef TIMECOUNTER_DEBUG
	int64_t factor, old_factor;
#endif
	val = cc_cal_val;

	s = splhigh();
	/* create next generation number */
	gen = ci->ci_cc.cc_gen;
	gen++;
	if (gen == 0)
		gen++;

	/* update in progress */
	ci->ci_cc.cc_gen = 0;

	denom = ci->ci_cc.cc_cc;
	ci->ci_cc.cc_cc = cpu_counter32();

	if (ci->ci_cc.cc_denom == 0) {
		/*
		 * This is our first time here on this CPU.  Just
		 * start with reasonable initial values.
		 */
		ci->ci_cc.cc_val = val;
		ci->ci_cc.cc_denom = cpu_frequency(ci);
		if (ci->ci_cc.cc_denom == 0)
			ci->ci_cc.cc_denom = cc_timecounter.tc_frequency;
		ci->ci_cc.cc_delta = ci->ci_cc.cc_denom;
		ci->ci_cc.cc_gen = gen;
		splx(s);
		return;
	}

#ifdef TIMECOUNTER_DEBUG
	old_factor = (ci->ci_cc.cc_delta * 1000 ) / ci->ci_cc.cc_denom;
#endif

	/* local ticks per period */
	denom = ci->ci_cc.cc_cc - denom;
	if (denom < 0)
		denom += 0x100000000LL;

	ci->ci_cc.cc_denom = denom;

	/* reference ticks per period */
	delta = val - ci->ci_cc.cc_val;
	if (delta < 0)
		delta += 0x100000000LL;

	ci->ci_cc.cc_val = val;
	ci->ci_cc.cc_delta = delta;
	
	/* publish new generation number */
	ci->ci_cc.cc_gen = gen;
	splx(s);

#ifdef TIMECOUNTER_DEBUG
	factor = (delta * 1000) / denom - old_factor;
	if (factor < 0)
		factor = -factor;

	if (factor > old_factor / 10)
		printf("cc_calibrate_cpu[%u]: 10%% exceeded - delta %"
		    PRId64 ", denom %" PRId64 ", factor %" PRId64
		    ", old factor %" PRId64"\n", ci->ci_index,
		    delta, denom, (delta * 1000) / denom, old_factor);
#endif /* TIMECOUNTER_DEBUG */
}
コード例 #7
0
ファイル: lcd.c プロジェクト: rcls/switchplus
void lcd_init (void)
{
    // Reset the SDRAM.
    meminit (cpu_frequency (1));

    puts ("LCD setup:");
    static const unsigned pins[] = {
        // Setup the PLL0AUDIO to give 74.75MHz off 50MHz ethernet clock.
        // ndec=122, mdec=13107, pdec=66
        // selr=0, seli=48, selp=24
        // pllfract = 47.839996,0x17eb85
        // pre-divider=16, feedback div=47, post-div=2
        // fcco=299MHz, fout=74.749994MHz.
        WORD_WRITE32n(PLL0AUDIO->ctrl, 4,
                      0x03001811,       // CTRL
                      13107,            // MDIV
                      66 + (122 << 12), // NP_DIV
                      0x17eb85),        // FRAC

        BIT_RESET(PLL0AUDIO->ctrl, 0),

        // Wait for lock.
        BIT_WAIT_ZERO(PLL0AUDIO->stat, 0),

        // The lcd clock is outclk11.  PLL0AUDIO is clock source 8.
        WORD_WRITE32(*BASE_LCD_CLK, 0x08000800),

        // Reset the lcd.
        WORD_WRITE32(RESET_CTRL[0], 1<<16),
        BIT_WAIT_SET(RESET_ACTIVE_STATUS[0], 16),

        // 1024x1024 59.90 Hz (CVT) hsync: 63.13 kHz; pclk: 74.75 MHz
        // Modeline "1024x1024R" 74.75  1024 1072 1104 1184  1024 1027 1037 1054
        // +hsync -vsync
        // horizontal 1024 48 32 80
        // vertical 1024 3 10 17

        WORD_WRITE32n(LCD->timh, 7,
                      (79 << 24) + (47 << 8) + (31 << 16) + 0xfc, // TIMH
                      (16 << 24) + (2 << 16) + (9 << 10) + 1023,  // TIMV
                      // PCD_LO = 0, Clock divisor = 0.
                      // CLK_SEL = 1, LCDCLKIN.
                      // ACB = 0, N/A.
                      // IVS=0, IHS=1, positive vsync, negative hsync (!?)
                      // IPC=1, falling clock edge.
                      // IOE=0, out enable positive.
                      // CPL=1023.
                      // BCD=1, no clock divider.
                      // PCD_HI=0.
                      0x07ff3020,                                 // POL
                      0,                                          // LE
                      (unsigned) FRAME_BUFFER,                    // UPBASE
                      (unsigned) FRAME_BUFFER,                    // LPBASE
                      LCD_CONTROL),

        // PIN_OUT_FAST(4,1,2),            // A1  LCD_VD0
        // PIN_OUT_FAST(4,3,2),            // C2  LCD_VD2
        // PIN_OUT_FAST(4,4,2),            // B1  LCD_VD1
        // PIN_OUT_FAST(4,8,2),            // E2  LCD_VD9
        // PIN_OUT_FAST(7,2,3),            // A16 LCD_VD18
        // PIN_OUT_FAST(7,3,3),            // C13 LCD_VD17
        // PIN_OUT_FAST(7,4,3),            // C8  LCD_VD16
        // PIN_OUT_FAST(7,5,3),            // A7  LCD_VD8
        //PIN_OUT_FAST(,,), // B16 LCD_LE
        //PIN_OUT_FAST(,,), // B6  LCD_PWR
        PIN_OUT_FAST(3,4,7)             // A15 LCD_VD13
        + PIN_EXTRA(1),                 // C12 LCD_VD12
        PIN_OUT_FAST(4,2,2),            // D3  LCD_VD3
        PIN_OUT_FAST(4,5,2)             // D2  LCD_FP
        + PIN_EXTRA(1),                 // C1  LCD_ENAB/LCDM
        PIN_OUT_FAST(4,9,2)             // L2  LCD_VD11
        + PIN_EXTRA(1),                 // M3  LCD_VD10
        PIN_OUT_FAST(7,1,4),            // C14 LCD_VD7
        PIN_OUT_FAST(7,6,3),            // C7  LCD_LP
        PIN_OUT_FAST(8,5,3)             // J1  LCD_VD6
        + PIN_EXTRA(2),                 // K3  LCD_VD5, K1  LCD_VD4
        PIN_OUT_FAST(11,0,2)            // B15 LCD_VD23
        + PIN_EXTRA(6),         // ... A13 VD20, B11 VD15, A12 VD14, A6 VD19
        PIN_OUT_FAST(12,0,4),           // D4  LCD_DCLK

        // Enable the lcd.
        BIT_SET(LCD->ctrl, 0), // TFT, 16bpp, 565, watermark=8.

        // Enable the frame interrupt.
        WORD_WRITE(LCD->intmsk, 4),
    };

    configure(pins, sizeof pins / sizeof pins[0]);

    NVIC_ISER[0] = 1 << m4_lcd;

    puts (" done\n");
}