mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
make lcd almost work
This commit is contained in:
@@ -111,9 +111,6 @@ start_idle: // 280
|
||||
// Wait for the next interrupt, then the first thread will be scheduled.
|
||||
// It is impractical to try to call schedule, because for that the
|
||||
// idle task would need to own capabilities.
|
||||
move $v0, $zero
|
||||
syscall
|
||||
nop
|
||||
1: wait
|
||||
b 1b
|
||||
nop
|
||||
@@ -221,7 +218,8 @@ save_regs:
|
||||
#ifndef NDEBUG
|
||||
// Allow interrupts to set EPC and friends.
|
||||
mfc0 $k0, $CP0_STATUS
|
||||
andi $k0, $k0, 0xff00
|
||||
li $k1, 0x1000ff00
|
||||
and $k0, $k0, $k1
|
||||
mtc0 $k0, $CP0_STATUS
|
||||
#endif
|
||||
|
||||
|
||||
@@ -257,12 +257,14 @@ void init ():
|
||||
GPIO_GPDIR (GPIO_USB_CLK_EN_PORT) |= 1 << GPIO_USB_CLK_EN
|
||||
GPIO_GPDR (GPIO_USB_CLK_EN_PORT) |= 1 << GPIO_USB_CLK_EN
|
||||
|
||||
// Start the operating system timer.
|
||||
unsigned latch = (JZ_EXTAL + (HZ>>1)) / HZ
|
||||
// Start the operating system timer, and set it to give an interrupt immediately.
|
||||
// This is better, because the kernel start with jumping into the idle task and
|
||||
// waiting for the first interrupt.
|
||||
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_count (0, 0)
|
||||
ost_set_mode (0, OST_TCSR_UIE | OST_TCSR_CKS_EXTAL)
|
||||
ost_enable_channel (0)
|
||||
intc_unmask_irq (IRQ_OST0)
|
||||
|
||||
@@ -19,11 +19,40 @@
|
||||
#define ARCH
|
||||
#include "../kernel.hh"
|
||||
|
||||
static void handle_exit (Thread *old_current):
|
||||
if !current:
|
||||
schedule ()
|
||||
if !current:
|
||||
current = &idle
|
||||
if old_current == current:
|
||||
return
|
||||
if current != &idle:
|
||||
if (Memory *)asids[current->address_space->arch.asid] != current->address_space:
|
||||
if asids[0]:
|
||||
current->address_space->arch.asid = asids[0]
|
||||
asids[0] = asids[asids[0]]
|
||||
else:
|
||||
static unsigned random = 1
|
||||
current->address_space->arch.asid = random
|
||||
// Overwrite used asid, so flush those values from tlb.
|
||||
flush_tlb (random)
|
||||
++random
|
||||
if random >= 64:
|
||||
random = 1
|
||||
asids[current->address_space->arch.asid] = (unsigned)current->address_space
|
||||
cp0_set (CP0_ENTRY_HI, current->address_space->arch.asid)
|
||||
directory = current->address_space->arch.directory
|
||||
if current->flags & THREAD_FLAG_PRIV:
|
||||
cp0_set (CP0_STATUS, 0x1000ff13)
|
||||
else:
|
||||
cp0_set (CP0_STATUS, 0x0000ff13)
|
||||
|
||||
/// A TLB miss has occurred. This is the slow version. It is only used
|
||||
/// when k0 or k1 is not 0, or when an error occurs.
|
||||
/// Otherwise, the ultra-fast code in entry.S is used.
|
||||
Thread *tlb_refill ():
|
||||
//panic (0x88776655, "TLB refill")
|
||||
Thread *old_current = current
|
||||
if !directory:
|
||||
panic (0x44449999, "No directory")
|
||||
unsigned EntryHi
|
||||
@@ -41,11 +70,13 @@ Thread *tlb_refill ():
|
||||
cp0_set (CP0_ENTRY_LO0, t[idx])
|
||||
cp0_set (CP0_ENTRY_LO1, t[idx + 1])
|
||||
__asm__ volatile ("tlbwr")
|
||||
handle_exit (old_current)
|
||||
return current
|
||||
|
||||
/// An interrupt which is not an exception has occurred.
|
||||
Thread *interrupt ():
|
||||
//panic (0x88877722, "Interrupt")
|
||||
Thread *old_current = current
|
||||
//dbg_send (INTC_IPR)
|
||||
unsigned ipr = INTC_IPR
|
||||
for unsigned i = 0; i < 32; ++i:
|
||||
@@ -68,6 +99,7 @@ Thread *interrupt ():
|
||||
ost_clear_uf (0)
|
||||
intc_ack_irq (IRQ_OST0)
|
||||
timer_interrupt ()
|
||||
handle_exit (old_current)
|
||||
return current
|
||||
|
||||
void flush_tlb (unsigned asid):
|
||||
@@ -87,10 +119,9 @@ static void arch_invoke ():
|
||||
Thread *caller = current
|
||||
target = caller->address_space->find_capability (caller->arch.v0, &wait)
|
||||
if !target:
|
||||
// TODO: there must be no action here. This is just because the rest doesn't work yet.
|
||||
dbg_send (3, 2)
|
||||
// There must be no action here.
|
||||
//dbg_send (3, 2)
|
||||
//dbg_send (caller->arch.v0)
|
||||
schedule ()
|
||||
// Calling an invalid capability always fails.
|
||||
caller->arch.v0 = 0
|
||||
else:
|
||||
@@ -108,35 +139,10 @@ static void arch_invoke ():
|
||||
caller->arch.v0 = target->invoke (&c) ? 1 : 0
|
||||
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]:
|
||||
current->address_space->arch.asid = asids[0]
|
||||
asids[0] = asids[asids[0]]
|
||||
else:
|
||||
static unsigned random = 1
|
||||
current->address_space->arch.asid = random
|
||||
// Overwrite used asid, so flush those values from tlb.
|
||||
flush_tlb (random)
|
||||
++random
|
||||
if random >= 64:
|
||||
random = 1
|
||||
asids[current->address_space->arch.asid] = (unsigned)current->address_space
|
||||
cp0_set (CP0_ENTRY_HI, current->address_space->arch.asid)
|
||||
directory = current->address_space->arch.directory
|
||||
unsigned status
|
||||
cp0_get (CP0_STATUS, status)
|
||||
status &= 0x0fffffff
|
||||
if current->flags & THREAD_FLAG_PRIV:
|
||||
status |= 0x10000000
|
||||
cp0_set (CP0_STATUS, status | 0x13)
|
||||
|
||||
/// A general exception has occurred.
|
||||
Thread *exception ():
|
||||
Thread *old_current = current
|
||||
unsigned cause
|
||||
cp0_get (CP0_CAUSE, cause)
|
||||
switch (cause >> 2) & 0x1f:
|
||||
@@ -220,9 +226,12 @@ Thread *exception ():
|
||||
panic (0xf5223344, "Reserved exception code")
|
||||
default:
|
||||
panic (0xf6223344, "Impossible exception code")
|
||||
handle_exit (old_current)
|
||||
return current
|
||||
|
||||
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
||||
Thread *cache_error ():
|
||||
panic (0x33333333, "cache error")
|
||||
Thread *old_current = current
|
||||
handle_exit (old_current)
|
||||
return current
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
// Main clock, for cpu, serial port, and with divisors for most other hardware
|
||||
#define JZ_EXTAL 3686400
|
||||
//#define JZ_EXTAL 3072000
|
||||
// RTC clock
|
||||
#define RTC_CLOCK 32768
|
||||
|
||||
@@ -2311,8 +2312,9 @@ static __inline__ void udelay (unsigned us):
|
||||
GPIO_GPDR (0) = GPIO_GPDR (0)
|
||||
|
||||
#ifndef __KERNEL
|
||||
static __inline__ void mdelay (unsigned ms):
|
||||
my_sleep ((ms + 99) / 100)
|
||||
static __inline__ void ddelay (unsigned ds):
|
||||
Message m
|
||||
my_sleep (ds, &m)
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
@@ -109,6 +109,6 @@ void dbg_send (unsigned code, unsigned bits):
|
||||
dbg_led (false, false, false)
|
||||
dbg_sleep (200)
|
||||
dbg_led (true, true, false)
|
||||
dbg_sleep (500)
|
||||
dbg_sleep (50)
|
||||
dbg_led (false, false, false)
|
||||
dbg_sleep (500)
|
||||
dbg_sleep (50)
|
||||
|
||||
Reference in New Issue
Block a user