From 71799af2d5e1a71abcb4c830af371fa28c85d3c1 Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Tue, 23 Jan 2007 08:01:20 +0000 Subject: [PATCH] Cleaned up declaration and initialization of clock_lock. It is only used by clock code, so don't export it to the world for machdep.c to initialize. There is a minor problem initializing it before it is used, since although clock initialization is split up so that parts of it can be done early, the first part was never done early enough to actually work. Split it up a bit more and do the first part as late as possible to document the necessary order. The functions that implement the split are still bogusly exported. Cleaned up initialization of the i8254 clock hardware using the new split. Actually initialize it early enough, and don't work around it not being initialized in DELAY() when DELAY() is called early for initialization of some console drivers. This unfortunately moves a little more code before the early debugger breakpoint so that it is harder to debug. The ordering of console and related initialization is delicate because we want to do as little as possible before the breakpoint, but must initialize a console. --- sys/amd64/amd64/machdep.c | 7 ++++++- sys/amd64/include/clock.h | 3 ++- sys/amd64/isa/clock.c | 23 ++++++++++------------- sys/i386/i386/machdep.c | 7 ++++++- sys/i386/include/clock.h | 3 ++- sys/i386/isa/clock.c | 23 ++++++++++------------- sys/isa/atrtc.c | 23 ++++++++++------------- 7 files changed, 46 insertions(+), 43 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 905b4903a22..2aac078aa67 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1176,7 +1176,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) * under witness. */ mutex_init(); - mtx_init(&clock_lock, "clk", NULL, MTX_SPIN); mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS); /* exceptions */ @@ -1206,6 +1205,12 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) r_idt.rd_base = (long) idt; lidt(&r_idt); + /* + * Initialize the i8254 before the console so that console + * initialization can use DELAY(). + */ + i8254_init(); + /* * Initialize the console before we print anything out. */ diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h index 36d0bebe00c..30c2f26ec7c 100644 --- a/sys/amd64/include/clock.h +++ b/sys/amd64/include/clock.h @@ -22,7 +22,8 @@ extern u_int timer_freq; extern int timer0_max_count; extern uint64_t tsc_freq; extern int tsc_is_broken; -extern struct mtx clock_lock; + +void i8254_init(void); /* * Driver to clock driver interface. diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index 0b1fc4d636c..e548b262ac1 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -103,11 +103,11 @@ int statclock_disable; u_int timer_freq = TIMER_FREQ; int timer0_max_count; int timer0_real_max_count; -struct mtx clock_lock; #define RTC_LOCK mtx_lock_spin(&clock_lock) #define RTC_UNLOCK mtx_unlock_spin(&clock_lock) static int beeping = 0; +static struct mtx clock_lock; static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; static struct intsrc *i8254_intsrc; static u_int32_t i8254_lastcount; @@ -294,13 +294,6 @@ DELAY(int n) if (state == 1) printf("DELAY(%d)...", n); #endif - /* - * Guard against the timer being uninitialized if we are called - * early for console i/o. - */ - if (timer0_max_count == 0) - set_timer_freq(timer_freq, hz); - /* * Read the counter first, so that the rest of the setup overhead is * counted. Guess the initial overhead is 20 usec (on most systems it @@ -560,10 +553,15 @@ set_timer_freq(u_int freq, int intr_freq) mtx_unlock_spin(&clock_lock); } -/* - * Initialize 8254 timer 0 early so that it can be used in DELAY(). - * XXX initialization of other timers is unintentionally left blank. - */ +/* This is separate from startrtclock() so that it can be called early. */ +void +i8254_init(void) +{ + + mtx_init(&clock_lock, "clk", NULL, MTX_SPIN); + set_timer_freq(timer_freq, hz); +} + void startrtclock() { @@ -572,7 +570,6 @@ startrtclock() writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); - set_timer_freq(timer_freq, hz); freq = calibrate_clocks(); #ifdef CLK_CALIBRATION_LOOP if (bootverbose) { diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 01348d552b8..7d649e48663 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -2118,7 +2118,6 @@ init386(first) * under witness. */ mutex_init(); - mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE); mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS | MTX_NOPROFILE); /* make ldt memory segments */ @@ -2201,6 +2200,12 @@ init386(first) } #endif /* XBOX */ + /* + * Initialize the i8254 before the console so that console + * initialization can use DELAY(). + */ + i8254_init(); + /* * Initialize the console before we print anything out. */ diff --git a/sys/i386/include/clock.h b/sys/i386/include/clock.h index 74679b9210c..a91b2524873 100644 --- a/sys/i386/include/clock.h +++ b/sys/i386/include/clock.h @@ -22,7 +22,8 @@ extern u_int timer_freq; extern int timer0_max_count; extern uint64_t tsc_freq; extern int tsc_is_broken; -extern struct mtx clock_lock; + +void i8254_init(void); /* * Driver to clock driver interface. diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index bc0bf61feed..29ddd39bf3c 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -106,11 +106,11 @@ int statclock_disable; u_int timer_freq = TIMER_FREQ; int timer0_max_count; int timer0_real_max_count; -struct mtx clock_lock; #define RTC_LOCK mtx_lock_spin(&clock_lock) #define RTC_UNLOCK mtx_unlock_spin(&clock_lock) static int beeping = 0; +static struct mtx clock_lock; static struct intsrc *i8254_intsrc; static u_int32_t i8254_lastcount; static u_int32_t i8254_offset; @@ -301,13 +301,6 @@ DELAY(int n) if (state == 1) printf("DELAY(%d)...", n); #endif - /* - * Guard against the timer being uninitialized if we are called - * early for console i/o. - */ - if (timer0_max_count == 0) - set_timer_freq(timer_freq, hz); - /* * Read the counter first, so that the rest of the setup overhead is * counted. Guess the initial overhead is 20 usec (on most systems it @@ -605,10 +598,15 @@ timer_restore(void) rtc_restore(); /* reenable RTC interrupts */ } -/* - * Initialize 8254 timer 0 early so that it can be used in DELAY(). - * XXX initialization of other timers is unintentionally left blank. - */ +/* This is separate from startrtclock() so that it can be called early. */ +void +i8254_init(void) +{ + + mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE); + set_timer_freq(timer_freq, hz); +} + void startrtclock() { @@ -617,7 +615,6 @@ startrtclock() writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); - set_timer_freq(timer_freq, hz); freq = calibrate_clocks(); #ifdef CLK_CALIBRATION_LOOP if (bootverbose) { diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index bc0bf61feed..29ddd39bf3c 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -106,11 +106,11 @@ int statclock_disable; u_int timer_freq = TIMER_FREQ; int timer0_max_count; int timer0_real_max_count; -struct mtx clock_lock; #define RTC_LOCK mtx_lock_spin(&clock_lock) #define RTC_UNLOCK mtx_unlock_spin(&clock_lock) static int beeping = 0; +static struct mtx clock_lock; static struct intsrc *i8254_intsrc; static u_int32_t i8254_lastcount; static u_int32_t i8254_offset; @@ -301,13 +301,6 @@ DELAY(int n) if (state == 1) printf("DELAY(%d)...", n); #endif - /* - * Guard against the timer being uninitialized if we are called - * early for console i/o. - */ - if (timer0_max_count == 0) - set_timer_freq(timer_freq, hz); - /* * Read the counter first, so that the rest of the setup overhead is * counted. Guess the initial overhead is 20 usec (on most systems it @@ -605,10 +598,15 @@ timer_restore(void) rtc_restore(); /* reenable RTC interrupts */ } -/* - * Initialize 8254 timer 0 early so that it can be used in DELAY(). - * XXX initialization of other timers is unintentionally left blank. - */ +/* This is separate from startrtclock() so that it can be called early. */ +void +i8254_init(void) +{ + + mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE); + set_timer_freq(timer_freq, hz); +} + void startrtclock() { @@ -617,7 +615,6 @@ startrtclock() writertc(RTC_STATUSA, rtc_statusa); writertc(RTC_STATUSB, RTCSB_24HR); - set_timer_freq(timer_freq, hz); freq = calibrate_clocks(); #ifdef CLK_CALIBRATION_LOOP if (bootverbose) {