1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-12-29 20:31:09 +02:00

Working timer

This commit is contained in:
Bas Wijnen 2009-07-04 16:21:28 +02:00
parent d136712524
commit eb141d7901
12 changed files with 142 additions and 105 deletions

View File

@ -179,6 +179,7 @@ Thread *Memory::alloc_thread ():
ret->pc = 0
ret->sp = 0
Thread_arch_init (ret)
ret->sleep = 0
ret->flags = 0
ret->schedule_prev = NULL
ret->schedule_next = NULL

View File

@ -27,13 +27,13 @@
#define SPDA (1 << 2) //LCD_PS
#define LCD_RET (1 << 3) //LCD_REV //use for lcd reset
// level is in the range [0, 300]
static void set_backlight (unsigned level):
PWM_DUT (0) = level
if level:
static void set_backlight (bool state):
if state:
PWM_DUT (0) = 300
PWM_CTR (0) = 0xbf
GPIO_GPDR (2) |= PWM_ENABLE
else:
PWM_DUT (0) = 0
PWM_CTR (0) = 0x3f
GPIO_GPDR (2) &= ~PWM_ENABLE
@ -60,9 +60,9 @@ static void write_reg (unsigned reg, unsigned value):
static void lcd_enable ():
udelay (50)
GPIO_GPDR (2) &= ~LCD_RET
mdelay(150)
udelay(150000)
GPIO_GPDR (2) |= LCD_RET
mdelay(10)
udelay(10000)
// These values have been copied from the linux source.
// I have no idea what they do.
write_reg (0x00, 0x03)
@ -78,24 +78,30 @@ static void lcd_enable ():
write_reg (0x0B, 0xc6)
write_reg (0x0C, 0x20)
write_reg (0x0D, 0x20)
set_backlight (300)
set_backlight (true)
static void lcd_disable ():
write_reg (0x00, 0x03)
set_backlight (0)
set_backlight (false)
static void reset ():
gpio_as_pwm ()
gpio_as_lcd_master ()
GPIO_GPDR (2) &= ~PWM_ENABLE
PWM_CTR (0) = 0x3f
PWM_PER (0) = 300
pwm_set_duty (0, 300)
pwm_set_full_duty (0)
// initialize things.
GPIO_GPIER (2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
GPIO_GPDIR (2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
udelay (50)
GPIO_GPDR (2) &= ~LCD_RET
mdelay (150)
udelay (150000)
GPIO_GPDR (2) |= LCD_RET
mdelay (10)
udelay (10000)
lcd_enable ()
// For now, support only 16 bpp.
@ -112,7 +118,7 @@ static void reset ():
CPM_MSCR |= 1 << 7
unsigned pclk = 60 * (800 * 3 + 80) * 500
unsigned pllout = get_pllout ()
unsigned pllout = cpm_get_pllout ()
CPM_CFCR2 = pllout / pclk - 1
unsigned v = pllout / (pclk * 4) - 1
while v < 0xf && pllout / (v + 1) > 150000000:
@ -121,7 +127,7 @@ static void reset ():
// Start lcd.
CPM_MSCR &= ~(1 << 7)
mdelay (1)
udelay (1000)
int main ():
map_gpio ()
@ -132,11 +138,11 @@ int main ():
reset ()
while true:
for unsigned i = 0; i <= 300; i += 30:
set_backlight (i)
kdebug (0)
mdelay (50)
schedule ()
set_backlight (false)
kdebug (0)
set_backlight (true)
kdebug (0)
schedule ()
while true:
Message msg
@ -144,7 +150,7 @@ int main ():
continue
switch msg.protected_data:
case LCD_BACKLIGHT:
set_backlight (msg.data[0] > 300 ? 300 : msg.data[0])
set_backlight (msg.data[0])
break
case LCD_RESET:
reset ()

View File

@ -327,6 +327,9 @@ static void thread_invoke (unsigned target, unsigned protected_data, Capability:
else
thread->unrun ()
break
case CAP_THREAD_INFO_SLEEP:
value = &thread->sleep
break
default:
value = Thread_arch_info (thread, c->data[1])
break

16
iris.h
View File

@ -79,6 +79,7 @@ extern "C" {
#define CAP_THREAD_INFO_PC ~0
#define CAP_THREAD_INFO_SP ~1
#define CAP_THREAD_INFO_FLAGS ~2
#define CAP_THREAD_INFO_SLEEP ~3
/* Flag values for processor state */
#define THREAD_FLAG_PRIV 0x80000000
#define THREAD_FLAG_WAITING 0x40000000
@ -495,6 +496,21 @@ static unsigned thread_wait (Capability thread, int wait)
return thread_flags (thread, wait ? THREAD_FLAG_WAITING : 0, THREAD_FLAG_WAITING);
}
static unsigned thread_sleep (Capability thread, unsigned value)
{
return thread_info (thread, CAP_THREAD_INFO_SLEEP, value, ~0);
}
static void my_sleep (unsigned value)
{
call_n04 (__my_thread, CAP_THREAD_INFO, CAP_THREAD_INFO_SLEEP, value, ~0);
}
static unsigned thread_get_sleep (Capability thread)
{
return thread_info (thread, CAP_THREAD_INFO_SLEEP, 0, 0);
}
static unsigned thread_get_pc (Capability thread)
{
return thread_info (thread, CAP_THREAD_INFO_PC, 0, 0);

View File

@ -73,6 +73,7 @@ struct Thread : public Object <Thread>:
unsigned pc, sp
Thread_arch arch
unsigned flags
unsigned sleep
Thread *schedule_prev, *schedule_next
void run ()
void unrun ()
@ -181,7 +182,9 @@ extern "C":
void dbg_sleep (unsigned ms)
void dbg_send (unsigned code, unsigned bits = 32)
/// Defined in schedule.ccp
void schedule ()
void timer_interrupt ()
struct FreePage:
FreePage *next
@ -192,7 +195,7 @@ EXTERN Thread *sleepers, *runners
EXTERN Thread idle
EXTERN Memory idle_memory
EXTERN Page idle_page
EXTERN Thread *first_scheduled
EXTERN Thread *first_scheduled, *first_sleeper
EXTERN Thread *current
// Defined in alloc.cc

View File

@ -313,11 +313,8 @@ void Page_arch_update_mapping (Page *page):
void arch_register_interrupt (unsigned num, Receiver *r):
arch_interrupt_receiver[num] = r
unsigned status
cp0_get (CP0_STATUS, status)
// And enable or disable the interrupt.
if r:
status |= 1 << (num + 8)
intc_unmask_irq (num)
else:
status &= ~(1 << (num + 8))
cp0_set (CP0_STATUS, status)
intc_mask_irq (num)

View File

@ -36,9 +36,6 @@ start_hack_for_disassembler:
la $sp, kernel_stack + KERNEL_STACK_SIZE
// Disable interrupts during bootstrap.
mtc0 $zero, $Status
// TODO: flush cache and optionally refill it.
// Set kseg0 cachable.

View File

@ -80,8 +80,6 @@ addr_100:
.fill 0x180 - (. - addr_000)
addr_180:
// General exception
// Allow new exceptions to update EPC and friends.
mtc0 $zero, $CP0_STATUS
sw $ra, -0xd88($zero)
bal save_regs
nop
@ -122,6 +120,12 @@ start_idle: // 280
// TODO: save only fragile registers now, the rest on task switch.
kernel_exit:
#ifndef NDEBUG
// Allow interrupts to set EPC and friends.
mfc0 $k0, $CP0_STATUS
ori $k0, $k0, 0xff13
mtc0 $k0, $CP0_STATUS
#endif
lw $k0, SAVE_PC($v0)
mtc0 $k0, $CP0_EPC
lw $k0, SAVE_LO($v0)
@ -213,6 +217,14 @@ save_regs:
lw $gp, -0xd84($zero)
la $sp, kernel_stack + KERNEL_STACK_SIZE
#ifndef NDEBUG
// Allow interrupts to set EPC and friends.
mfc0 $k0, $CP0_STATUS
andi $k0, $k0, 0xff00
mtc0 $k0, $CP0_STATUS
#endif
move $t9, $ra
la $ra, kernel_exit
jr $t9

View File

@ -110,6 +110,7 @@ static unsigned mkcap (Memory *mem, unsigned type, void *obj):
static void init_threads ():
Thread *previous = NULL
first_scheduled = NULL
first_sleeper = NULL
for unsigned i = 0; i < NUM_THREADS; ++i:
Memory *mem = top_memory.alloc_memory ()
Thread *thread = mem->alloc_thread ()
@ -249,20 +250,22 @@ void init ():
gpio_as_eth ()
gpio_as_usb ()
gpio_as_lcd_master ()
gpio_as_ssi()
gpio_as_msc ()
GPIO_GPDIR (GPIO_PWM0_PORT) |= 1 << GPIO_PWM0
GPIO_GPDR (GPIO_PWM0_PORT) |= 1 << GPIO_PWM0
GPIO_GPDIR (GPIO_USB_CLK_EN_PORT) |= 1 << GPIO_USB_CLK_EN
GPIO_GPDR (GPIO_USB_CLK_EN_PORT) |= 1 << GPIO_USB_CLK_EN
dbg_send (cpm_get_pllout ())
// Start the operating system timer.
unsigned latch = (JZ_EXTAL + (HZ>>1)) / HZ
ost_disable_all ()
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
ost_set_reload (0, latch)
ost_set_count (0, latch)
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
ost_enable_channel (0)
intc_unmask_irq (IRQ_OST0)
// Unset all interrupt handlers.
for unsigned i = 0; i < 32; ++i:
@ -270,7 +273,7 @@ void init ():
// Say we're handling an exception. Since we're going to enter the idle task, allow access to cp0.
// All interrupts enter the CPU through the interrupt controller at IP2, so enable that.
cp0_set (CP0_STATUS, 0x10000413)
cp0_set (CP0_STATUS, 0x1000ff13)
// Done; return to user space (the idle task).
__asm__ volatile ("eret")

View File

@ -43,16 +43,19 @@ Thread *tlb_refill ():
__asm__ volatile ("tlbwr")
return current
static void timer_interrupt ():
/// An interrupt which is not an exception has occurred.
Thread *interrupt ():
panic (0x88877722, "Interrupt")
//panic (0x88877722, "Interrupt")
//dbg_send (INTC_IPR)
unsigned ipr = INTC_IPR
for unsigned i = 1; i < 32; ++i:
for unsigned i = 0; i < 32; ++i:
if ipr & (1 << i):
// Handle timer interrupts specially: don't disable them.
if i == IRQ_OST0:
continue
// Disable the interrupt while handling it.
intc_mask_irq (i)
intc_ack_irq (i)
// Send message to interrupt handler.
if arch_interrupt_receiver[i]:
Capability::Context c
@ -61,9 +64,9 @@ Thread *interrupt ():
c.cap[j] = NULL
c.copy[j] = false
arch_interrupt_receiver[i]->send_message (i, &c)
if ipr & 1:
if ipr & (1 << IRQ_OST0):
ost_clear_uf (0)
intc_ack_irq (0)
intc_ack_irq (IRQ_OST0)
timer_interrupt ()
return current
@ -103,13 +106,12 @@ static void arch_invoke ():
c.data[2] = caller->arch.t2
c.data[3] = caller->arch.t3
caller->arch.v0 = target->invoke (&c) ? 1 : 0
if !current:
if caller != &idle && (caller->flags & (THREAD_FLAG_RUNNING | THREAD_FLAG_WAITING)) == THREAD_FLAG_RUNNING:
current = caller
else:
schedule ()
if !current:
current = &idle
if caller != current && caller != &idle && (caller->flags & (THREAD_FLAG_RUNNING | THREAD_FLAG_WAITING)) == THREAD_FLAG_RUNNING:
current = caller
else if !current:
schedule ()
if !current:
current = &idle
if caller != current:
if (Memory *)asids[current->address_space->arch.asid] != current->address_space:
if asids[0]:

View File

@ -179,7 +179,7 @@ static void __map_io (unsigned physical, unsigned mapping):
#define REG32(x) (*(volatile unsigned *)(x))
/*************************************************************************
* MSC
* MSC mmc/sd controller
*************************************************************************/
#define MSC_STRPCL REG16 (MSC_BASE + 0x000)
#define MSC_STAT REG32 (MSC_BASE + 0x004)
@ -302,7 +302,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* RTC
* RTC real-time clock
*************************************************************************/
#define RTC_RCR REG32 (RTC_BASE + 0x00)
#define RTC_RSR REG32 (RTC_BASE + 0x04)
@ -326,7 +326,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* FIR
* FIR fast infrared(?)
*************************************************************************/
#define FIR_TDR REG8 (FIR_BASE + 0x000)
#define FIR_RDR REG8 (FIR_BASE + 0x004)
@ -389,7 +389,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* SCC
* SCC smart card controller (unused in trendtac)
*************************************************************************/
#define SCC_DR(base) REG8 ((base) + 0x000)
#define SCC_FDR(base) REG8 ((base) + 0x004)
@ -456,7 +456,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* ETH
* ETH ethernet
*************************************************************************/
#define ETH_BMR REG32 (ETH_BASE + 0x1000)
#define ETH_TPDR REG32 (ETH_BASE + 0x1004)
@ -692,7 +692,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* WDT
* WDT watch-dog timer
*************************************************************************/
#define WDT_WTCSR REG8 (WDT_BASE + 0x00)
#define WDT_WTCNT REG32 (WDT_BASE + 0x04)
@ -703,7 +703,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* OST
* OST operating system timer
*************************************************************************/
#define OST_TER REG8 (OST_BASE + 0x00)
#define OST_TRDR(n) REG32 (OST_BASE + 0x10 + ((n) * 0x20))
@ -723,21 +723,8 @@ static void __map_io (unsigned physical, unsigned mapping):
#define OST_TCSR_CKS_RTCCLK (4 << OST_TCSR_CKS_BIT)
#define OST_TCSR_CKS_EXTAL (5 << OST_TCSR_CKS_BIT)
#define OST_TCSR0 OST_TCSR(0)
#define OST_TCSR1 OST_TCSR(1)
#define OST_TCSR2 OST_TCSR(2)
#define OST_TRDR0 OST_TRDR(0)
#define OST_TRDR1 OST_TRDR(1)
#define OST_TRDR2 OST_TRDR(2)
#define OST_TCNT0 OST_TCNT(0)
#define OST_TCNT1 OST_TCNT(1)
#define OST_TCNT2 OST_TCNT(2)
#define OST_TCRB0 OST_TCRB(0)
#define OST_TCRB1 OST_TCRB(1)
#define OST_TCRB2 OST_TCRB(2)
/*************************************************************************
* UART
* UART universal asynchronous receiver/transmitter (serial ports)
*************************************************************************/
#define IRDA_BASE UART0_BASE
@ -924,7 +911,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* INTC
* INTC interrupt controller
*************************************************************************/
#define INTC_ISR REG32 (INTC_BASE + 0x00)
#define INTC_IMR REG32 (INTC_BASE + 0x04)
@ -965,7 +952,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* CIM
* CIM camera interface module (not used in trendtac)
*************************************************************************/
#define CIM_CFG REG32 (CIM_BASE + 0x0000)
#define CIM_CTRL REG32 (CIM_BASE + 0x0004)
@ -1066,7 +1053,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* PWM
* PWM pulse width modulator: 0 is connected to lcd backlight; 1 maybe to a beeper
*************************************************************************/
#define PWM_CTR(n) REG8 (PWM##n##_BASE + 0x000)
#define PWM_PER(n) REG16 (PWM##n##_BASE + 0x004)
@ -1094,7 +1081,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* EMC
* EMC ?
*************************************************************************/
#define EMC_BCR REG32 (EMC_BASE + 0x00)
#define EMC_SMCR0 REG32 (EMC_BASE + 0x10)
@ -1305,7 +1292,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* GPIO
* GPIO general purpose input/output
*************************************************************************/
#define GPIO_GPDR(n) REG32 (GPIO_BASE + (0x00 + (n)*0x30))
#define GPIO_GPDIR(n) REG32 (GPIO_BASE + (0x04 + (n)*0x30))
@ -1329,7 +1316,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* HARB
* HARB ?
*************************************************************************/
#define HARB_HAPOR REG32 (HARB_BASE + 0x000)
#define HARB_HMCTR REG32 (HARB_BASE + 0x010)
@ -1383,7 +1370,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* I2C
* I2C inter-IC
*************************************************************************/
#define I2C_DR REG8 (I2C_BASE + 0x000)
#define I2C_CR REG8 (I2C_BASE + 0x004)
@ -1410,7 +1397,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* UDC
* UDC usb device controller (unused in trendtac)
*************************************************************************/
#define UDC_EP0InCR REG32 (UDC_BASE + 0x00)
#define UDC_EP0InSR REG32 (UDC_BASE + 0x04)
@ -1585,7 +1572,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* DMAC
* DMAC dma controller
*************************************************************************/
#define DMAC_DSAR(n) REG32 (DMAC_BASE + (0x00 + (n) * 0x20))
#define DMAC_DDAR(n) REG32 (DMAC_BASE + (0x04 + (n) * 0x20))
@ -1739,7 +1726,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* AIC
* AIC ac97/i2s controller (sound)
*************************************************************************/
#define AIC_FR REG32 (AIC_BASE + 0x000)
#define AIC_CR REG32 (AIC_BASE + 0x004)
@ -1900,7 +1887,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* LCD
* LCD liquid crystal display
*************************************************************************/
#define LCD_CFG REG32 (LCD_BASE + 0x00)
#define LCD_VSYNC REG32 (LCD_BASE + 0x04)
@ -2019,7 +2006,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* DES
* DES ?
*************************************************************************/
#define DES_CR1 REG32 (DES_BASE + 0x000)
#define DES_CR2 REG32 (DES_BASE + 0x004)
@ -2059,7 +2046,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* CPM
* CPM C? power management
*************************************************************************/
#define CPM_CFCR REG32 (CPM_BASE+0x00)
#define CPM_PLCR1 REG32 (CPM_BASE+0x10)
@ -2183,7 +2170,7 @@ static void __map_io (unsigned physical, unsigned mapping):
/*************************************************************************
* SSI
* SSI ? (audio serial bus?)
*************************************************************************/
#define SSI_DR REG32 (SSI_BASE + 0x001)
#define SSI_CR0 REG16 (SSI_BASE + 0x004)
@ -2323,8 +2310,10 @@ static __inline__ void udelay (unsigned us):
for unsigned k = 0; k < 100; ++k:
GPIO_GPDR (0) = GPIO_GPDR (0)
#ifndef __KERNEL
static __inline__ void mdelay (unsigned ms):
udelay (1000 * ms)
my_sleep ((ms + 99) / 100)
#endif
/***************************************************************************
* MSC
@ -2647,18 +2636,17 @@ static __inline__ unsigned msc_calc_slow_clk_divisor (bool is_sd):
#define ost_disable_all() ( OST_TER &= ~0x07 )
#define ost_enable_channel(n) ( OST_TER |= (1 << (n)) )
#define ost_disable_channel(n) ( OST_TER &= ~(1 << (n)) )
#define ost_set_reload(n, val) ( OST_TRDR(n) = (val) )
#define ost_set_count(n, val) ( OST_TCNT(n) = (val) )
#define ost_get_count(n) ( OST_TCNT(n) )
#define ost_set_clock(n, cs) do { OST_TCSR(n) &= ~OST_TCSR_CKS_MASK; OST_TCSR(n) |= cs; } while (0)
#define ost_set_mode(n, val) ( OST_TCSR(n) = (val) )
#define ost_enable_interrupt(n) ( OST_TCSR(n) |= OST_TCSR_UIE )
#define ost_disable_interrupt(n) ( OST_TCSR(n) &= ~OST_TCSR_UIE )
#define ost_uf_detected(n) ( OST_TCSR(n) & OST_TCSR_UF )
#define ost_clear_uf(n) ( OST_TCSR(n) &= ~OST_TCSR_UF )
#define ost_is_busy(n) ( OST_TCSR(n) & OST_TCSR_BUSY )
#define ost_clear_busy(n) ( OST_TCSR(n) &= ~OST_TCSR_BUSY )
#define ost_set_reload(n, val) ( OST_TRDR (n) = (val) )
#define ost_set_count(n, val) ( OST_TCNT (n) = (val) )
#define ost_get_count(n) ( OST_TCNT (n) )
#define ost_set_clock(n, cs) ( OST_TCSR (n) = OST_TCSR (n) & ~OST_TCSR_CKS_MASK | (cs) )
#define ost_set_mode(n, val) ( OST_TCSR (n) = (val) )
#define ost_enable_interrupt(n) ( OST_TCSR (n) |= OST_TCSR_UIE )
#define ost_disable_interrupt(n) ( OST_TCSR (n) &= ~OST_TCSR_UIE )
#define ost_uf_detected(n) ( OST_TCSR (n) & OST_TCSR_UF )
#define ost_clear_uf(n) ( OST_TCSR (n) &= ~OST_TCSR_UF )
#define ost_is_busy(n) ( OST_TCSR (n) & OST_TCSR_BUSY )
#define ost_clear_busy(n) ( OST_TCSR (n) &= ~OST_TCSR_BUSY )
/***************************************************************************
* UART
@ -3790,18 +3778,6 @@ static __inline__ void i2s_reset_codec ():
/***************************************************************************
* CPM
***************************************************************************/
static __inline__ unsigned int get_pllout ():
unsigned plcr = CPM_PLCR1
if plcr & CPM_PLCR1_PLL1EN:
unsigned nf, nr, no
unsigned od[4] = {1, 2, 2, 4}
nf = (plcr & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT
nr = (plcr & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT
no = od[((plcr & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)]
return (JZ_EXTAL) / ((nr+2) * no) * (nf+2)
else:
return JZ_EXTAL
#define cpm_plcr1_fd() ((CPM_PLCR1 & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT)
#define cpm_plcr1_rd() ((CPM_PLCR1 & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT)
#define cpm_plcr1_od() ((CPM_PLCR1 & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)

View File

@ -33,6 +33,12 @@ static void unrun_thread (Thread *thread):
first_scheduled = thread->schedule_next
if thread->schedule_next:
thread->schedule_next->schedule_prev = thread->schedule_prev
if thread->sleep:
thread->schedule_next = first_sleeper
thread->schedule_prev = NULL
if thread->schedule_next:
thread->schedule_next->schedule_prev = thread
first_sleeper = thread
void Thread::run ():
if flags & THREAD_FLAG_RUNNING:
@ -68,6 +74,21 @@ void Thread::unwait ():
if flags & THREAD_FLAG_RUNNING:
run_thread (this)
void timer_interrupt ():
//panic (0x88877744, "Timer interrupt")
Thread *thread, *next
for thread = first_sleeper; thread; thread = next:
next = thread->next
if !--thread->sleep:
if thread->flags & THREAD_FLAG_WAITING:
thread->unwait ()
else:
run_thread (thread)
//#ifndef NDEBUG
//static bool ledstate = false
//dbg_led (false, false, ledstate = !ledstate)
//#endif
void schedule ():
Thread *old = current
if current: