FOC: Basic Arndale multi-core support
Second CPU is up and receives timer interrupts. Caches are still disabled.
This commit is contained in:
@@ -85,7 +85,7 @@ config ABI_VF
|
|||||||
|
|
||||||
config PF_ARM_MP_CAPABLE
|
config PF_ARM_MP_CAPABLE
|
||||||
bool
|
bool
|
||||||
default y if ARM_MPCORE || ARM_CORTEX_A9
|
default y if ARM_MPCORE || ARM_CORTEX_A9 || ARM_CORTEX_A15
|
||||||
|
|
||||||
config CAN_ARM_CPU_SA1100
|
config CAN_ARM_CPU_SA1100
|
||||||
bool
|
bool
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ set_asid()
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
IMPLEMENTATION [arm && armv6plus && (mpcore || armca9)]:
|
IMPLEMENTATION [arm && armv6plus && (mpcore || armca9 || armca15)]:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -33,7 +33,7 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
IMPLEMENTATION [arm && armv6plus && !(mpcore || armca9)]:
|
IMPLEMENTATION [arm && armv6plus && !(mpcore || armca9 || armca15)]:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,17 +6,20 @@ PREPROCESS_PARTS += exynos5 libuart
|
|||||||
PREPROCESS_PARTS += $(if $(CONFIG_PF_EXYNOS5_ARNDALE), exynos5_arndale pic_gic)
|
PREPROCESS_PARTS += $(if $(CONFIG_PF_EXYNOS5_ARNDALE), exynos5_arndale pic_gic)
|
||||||
|
|
||||||
CONFIG_KERNEL_LOAD_ADDR := 0x40000000
|
CONFIG_KERNEL_LOAD_ADDR := 0x40000000
|
||||||
|
#no memory mapped SCU on exynos5
|
||||||
|
MPCORE_PHYS_BASE := 0x0
|
||||||
|
|
||||||
INTERFACES_KERNEL+= $(if $(CONFIG_PF_EXYNOS5_ARNDALE),gic)
|
INTERFACES_KERNEL+= $(if $(CONFIG_PF_EXYNOS5_ARNDALE),gic)
|
||||||
|
|
||||||
bootstrap_IMPL += bootstrap-arm-exynos5
|
bootstrap_IMPL += bootstrap-arm-exynos5
|
||||||
clock_IMPL += clock-generic
|
clock_IMPL += clock-generic
|
||||||
config_IMPL += config-arm-exynos5
|
config_IMPL += config-arm-exynos5
|
||||||
kernel_uart_IMPL += kernel_uart-arm-exynos5
|
kernel_uart_IMPL += kernel_uart-arm-exynos5
|
||||||
mem_layout_IMPL += mem_layout-arm-exynos5
|
mem_layout_IMPL += mem_layout-arm-exynos5
|
||||||
pic_IMPL += pic-gic pic-arm-gic-exynos5
|
pic_IMPL += pic-gic pic-arm-gic-exynos5
|
||||||
reset_IMPL += reset-arm-exynos5
|
platform_control_IMPL += platform_control-arm-exynos5
|
||||||
timer_IMPL += timer-arm-exynos5
|
reset_IMPL += reset-arm-exynos5
|
||||||
timer_tick_IMPL += timer_tick-single-vector
|
timer_IMPL += timer-arm-exynos5
|
||||||
uart_IMPL += uart-arm-exynos5
|
timer_tick_IMPL += timer_tick-multi-vector
|
||||||
warn_IMPL += warn warn-exynos5
|
uart_IMPL += uart-arm-exynos5
|
||||||
|
warn_IMPL += warn warn-exynos5
|
||||||
|
|||||||
@@ -16,4 +16,5 @@ map_hw(void *pd)
|
|||||||
map_dev<Mem_layout::Devices2_phys_base>(pd, 2);
|
map_dev<Mem_layout::Devices2_phys_base>(pd, 2);
|
||||||
map_dev<Mem_layout::Devices3_phys_base>(pd, 3);
|
map_dev<Mem_layout::Devices3_phys_base>(pd, 3);
|
||||||
map_dev<Mem_layout::Devices4_phys_base>(pd, 4);
|
map_dev<Mem_layout::Devices4_phys_base>(pd, 4);
|
||||||
|
map_dev<Mem_layout::Devices5_phys_base>(pd, 5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public:
|
|||||||
Devices2_phys_base = 0x12c00000,
|
Devices2_phys_base = 0x12c00000,
|
||||||
Devices3_phys_base = 0x10400000,
|
Devices3_phys_base = 0x10400000,
|
||||||
Devices4_phys_base = 0x12d00000,
|
Devices4_phys_base = 0x12d00000,
|
||||||
|
Devices5_phys_base = 0x02000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Virt_layout_exynos5 : Address {
|
enum Virt_layout_exynos5 : Address {
|
||||||
|
|||||||
@@ -29,3 +29,11 @@ IMPLEMENT inline
|
|||||||
void Pic::restore_all(Status)
|
void Pic::restore_all(Status)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
IMPLEMENTATION [arm && mp && pic_gic && exynos5]:
|
||||||
|
|
||||||
|
PUBLIC static
|
||||||
|
void Pic::init_ap(unsigned)
|
||||||
|
{
|
||||||
|
gic->init_ap();
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
INTERFACE [arm && mp && exynos5]:
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
IMPLEMENTATION [arm && mp && exynos5]:
|
||||||
|
|
||||||
|
#include "io.h"
|
||||||
|
#include "kmem.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
|
||||||
|
PUBLIC static
|
||||||
|
void
|
||||||
|
Platform_control::boot_ap_cpus(Address phys_tramp_mp_addr)
|
||||||
|
{
|
||||||
|
// Write start address to iRam base (0x2020000). This is checked by the app
|
||||||
|
// cpus wihtin an wfe (wait-for event) loop.
|
||||||
|
printf("START CPUs\n");
|
||||||
|
Io::write<Mword>(phys_tramp_mp_addr, Kmem::Devices5_map_base + 0x20000);
|
||||||
|
// wake-up cpus
|
||||||
|
asm volatile("dsb; sev" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
INTERFACE [arm & exynos5]:
|
INTERFACE [arm & exynos5]:
|
||||||
|
|
||||||
#include "kmem.h"
|
#include "kmem.h"
|
||||||
|
#include "processor.h"
|
||||||
|
|
||||||
EXTENSION class Timer
|
EXTENSION class Timer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
BASE = Kmem::Timer_map_base,
|
BASE = Kmem::Timer_map_base,
|
||||||
CFG0 = BASE,
|
CFG0 = BASE,
|
||||||
CFG1 = BASE + 0x4,
|
CFG1 = BASE + 0x4,
|
||||||
TCON = BASE + 0x8,
|
TCON = BASE + 0x8,
|
||||||
@@ -16,13 +17,15 @@ public:
|
|||||||
ONE_MS = 33000, /* HZ */
|
ONE_MS = 33000, /* HZ */
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned irq() { return 68; /* timer0 */ }
|
static unsigned irq() { return 68 + Proc::cpu_id(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
IMPLEMENTATION [arm && exynos5]:
|
IMPLEMENTATION [arm && exynos5]:
|
||||||
|
|
||||||
#include "mmu.h"
|
#include "cpu.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "irq_mgr.h"
|
||||||
|
#include "mmu.h"
|
||||||
|
|
||||||
IMPLEMENT inline
|
IMPLEMENT inline
|
||||||
void
|
void
|
||||||
@@ -31,25 +34,40 @@ Timer::update_one_shot(Unsigned64 wakeup)
|
|||||||
(void)wakeup;
|
(void)wakeup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
Mword
|
||||||
|
tcon_to_timer(Mword val, unsigned cpu_id)
|
||||||
|
{
|
||||||
|
return cpu_id == 0 ? val : (val << (4 + (4 * cpu_id)));
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT
|
IMPLEMENT
|
||||||
void Timer::init(unsigned)
|
void Timer::init(unsigned)
|
||||||
{
|
{
|
||||||
/* prescaler to one */
|
unsigned cpu_id = Proc::cpu_id();
|
||||||
Io::write<Mword>(0x1, CFG0);
|
|
||||||
/* divider to 1 */
|
|
||||||
Io::write<Mword>(0x0, CFG1);
|
|
||||||
|
|
||||||
/* program 1ms */
|
if (!Cpu::boot_cpu()->phys_id() == cpu_id)
|
||||||
Io::write<Mword>(ONE_MS, TCNTB0);
|
{
|
||||||
Io::write<Mword>(0x0, TCMPB0);
|
// prescaler to one
|
||||||
|
Io::write<Mword>(0x1, CFG0);
|
||||||
|
// divider to 1
|
||||||
|
Io::write<Mword>(0x0, CFG1);
|
||||||
|
}
|
||||||
|
// program 1ms
|
||||||
|
Mword offset = 0xc * cpu_id;
|
||||||
|
Io::write<Mword>(ONE_MS, TCNTB0 + offset);
|
||||||
|
Io::write<Mword>(0x0, TCMPB0 + offset);
|
||||||
|
|
||||||
/* enable IRQ */
|
// enable IRQ
|
||||||
Io::write<Mword>(0x1, TINT_STAT);
|
Io::set<Mword>(0x1 << cpu_id, TINT_STAT);
|
||||||
|
|
||||||
/* load and start timer in invterval mode*/
|
// load and start timer in invterval mode
|
||||||
Io::write<Mword>(0xa, TCON);
|
Mword tcon = Io::read<Mword>(TCON);
|
||||||
Io::write<Mword>(0x9, TCON);
|
Io::write<Mword>(tcon | tcon_to_timer(0xa, cpu_id), TCON);
|
||||||
|
Io::write<Mword>(tcon | tcon_to_timer(0x9, cpu_id), TCON);
|
||||||
|
|
||||||
|
// route IRQ to this CPU
|
||||||
|
Irq_mgr::mgr->set_cpu(irq(), cpu_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT inline NEEDS["config.h", "kip.h"]
|
IMPLEMENT inline NEEDS["config.h", "kip.h"]
|
||||||
@@ -65,5 +83,6 @@ Timer::system_clock()
|
|||||||
PUBLIC static inline NEEDS["io.h"]
|
PUBLIC static inline NEEDS["io.h"]
|
||||||
void Timer::acknowledge()
|
void Timer::acknowledge()
|
||||||
{
|
{
|
||||||
Io::set<Mword>(0x20, TINT_STAT);
|
Mword stat = Io::read<Mword>(TINT_STAT);
|
||||||
|
Io::write<Mword>(stat & (0x1f | (0x20 << Proc::cpu_id())), TINT_STAT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -309,7 +309,44 @@ Cpu::early_init_platform()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
IMPLEMENTATION [arm && !(mpcore || armca9)]:
|
IMPLEMENTATION [arm && armca15]:
|
||||||
|
PRIVATE static inline void
|
||||||
|
Cpu::early_init_platform()
|
||||||
|
{
|
||||||
|
Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_cpu_map_base + 0) | 1,
|
||||||
|
Mem_layout::Gic_cpu_map_base + 0);
|
||||||
|
Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_dist_map_base + 0) | 1,
|
||||||
|
Mem_layout::Gic_dist_map_base + 0);
|
||||||
|
|
||||||
|
Mem_unit::clean_dcache();
|
||||||
|
|
||||||
|
enable_smp();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
IMPLEMENTATION [arm && mp && (mpcore || armca9)]:
|
||||||
|
|
||||||
|
PUBLIC static inline NEEDS["mem_layout.h", "io.h"]
|
||||||
|
int
|
||||||
|
Cpu::num_cpus()
|
||||||
|
{
|
||||||
|
return (Io::read<Mword>(Mem_layout::Mp_scu_map_base + 4) & 3) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
IMPLEMENTATION [arm && mp && armca15]:
|
||||||
|
|
||||||
|
PUBLIC static inline int
|
||||||
|
Cpu::num_cpus()
|
||||||
|
{
|
||||||
|
unsigned num;
|
||||||
|
asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r"(num));
|
||||||
|
return ((num >> 24) & 0x3)+ 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
IMPLEMENTATION [arm && !(mpcore || armca9 || armca15)]:
|
||||||
|
|
||||||
PRIVATE static inline void Cpu::early_init_platform()
|
PRIVATE static inline void Cpu::early_init_platform()
|
||||||
{}
|
{}
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ Kernel_thread::boot_app_cpus()
|
|||||||
extern volatile Mword _tramp_mp_startup_pdbr;
|
extern volatile Mword _tramp_mp_startup_pdbr;
|
||||||
extern volatile Mword _tramp_mp_start_dcr;
|
extern volatile Mword _tramp_mp_start_dcr;
|
||||||
|
|
||||||
unsigned num_ap_cpus = (Io::read<Mword>(Mem_layout::Mp_scu_map_base + 4) & 3);
|
unsigned num_ap_cpus = Cpu::num_cpus();
|
||||||
|
|
||||||
printf("Number of CPUs: %d\n", num_ap_cpus + 1);
|
printf("Number of CPUs: %d\n", num_ap_cpus);
|
||||||
|
|
||||||
_tramp_mp_startup_cp15_c1 = Config::Cache_enabled
|
_tramp_mp_startup_cp15_c1 = Config::Cache_enabled
|
||||||
? Cpu::Cp15_c1_cache_enabled : Cpu::Cp15_c1_cache_disabled;
|
? Cpu::Cp15_c1_cache_enabled : Cpu::Cp15_c1_cache_disabled;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
INTERFACE[arm && !(mpcore || armca9)]:
|
INTERFACE[arm && !(mpcore || armca9 || armca15)]:
|
||||||
|
|
||||||
EXTENSION class Mem_page_attr
|
EXTENSION class Mem_page_attr
|
||||||
{
|
{
|
||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
INTERFACE[arm && (mpcore || armca9)]:
|
INTERFACE[arm && (mpcore || armca9 || armca15)]:
|
||||||
|
|
||||||
EXTENSION class Mem_page_attr
|
EXTENSION class Mem_page_attr
|
||||||
{
|
{
|
||||||
@@ -78,7 +78,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
INTERFACE[arm && armca9]:
|
INTERFACE[arm && (armca9 || armca15)]:
|
||||||
|
|
||||||
EXTENSION class Page_table
|
EXTENSION class Page_table
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
INTERFACE [arm && perf_cnt && !(mpcore || armca8 || armca9)]:
|
INTERFACE [arm && perf_cnt && !(mpcore || armca8 || armca9 || armca15)]:
|
||||||
|
|
||||||
EXTENSION class Perf_cnt
|
EXTENSION class Perf_cnt
|
||||||
{
|
{
|
||||||
@@ -81,7 +81,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
INTERFACE [arm && perf_cnt && (armca8 || armca9)]:
|
INTERFACE [arm && perf_cnt && (armca8 || armca9 || armca15)]:
|
||||||
|
|
||||||
EXTENSION class Perf_cnt
|
EXTENSION class Perf_cnt
|
||||||
{
|
{
|
||||||
@@ -184,7 +184,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
INTERFACE [arm && perf_cnt && armca9]:
|
INTERFACE [arm && perf_cnt && (armca9 || armca15)]:
|
||||||
|
|
||||||
EXTENSION class Perf_cnt
|
EXTENSION class Perf_cnt
|
||||||
{
|
{
|
||||||
@@ -199,7 +199,7 @@ private:
|
|||||||
IMPLEMENTATION [arm && perf_cnt]:
|
IMPLEMENTATION [arm && perf_cnt]:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
IMPLEMENTATION [arm && perf_cnt && !(mpcore || armca8 || armca9)]:
|
IMPLEMENTATION [arm && perf_cnt && !(mpcore || armca8 || armca9 || armca15)]:
|
||||||
|
|
||||||
char const *Perf_cnt::perf_type_str = "none";
|
char const *Perf_cnt::perf_type_str = "none";
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ Perf_cnt::mon_event_type(int nr)
|
|||||||
{ return Io::read<unsigned char>(mon_event_type_addr(nr)); }
|
{ return Io::read<unsigned char>(mon_event_type_addr(nr)); }
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
IMPLEMENTATION [arm && perf_cnt && (armca8 || armca9)]:
|
IMPLEMENTATION [arm && perf_cnt && (armca8 || armca9 || armca15)]:
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
|
|||||||
@@ -44,11 +44,13 @@ _tramp_mp_entry:
|
|||||||
msr cpsr_c, r0
|
msr cpsr_c, r0
|
||||||
|
|
||||||
// enable SMP
|
// enable SMP
|
||||||
|
#ifndef CONFIG_ARM_CORTEX_A15
|
||||||
adr r0, .Lmpcore_phys_base
|
adr r0, .Lmpcore_phys_base
|
||||||
ldr r0, [r0]
|
ldr r0, [r0]
|
||||||
ldr r1, [r0]
|
ldr r1, [r0]
|
||||||
orr r1, #1
|
orr r1, #1
|
||||||
str r1, [r0]
|
str r1, [r0]
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ARM_V7
|
#ifdef CONFIG_ARM_V7
|
||||||
bl invalidate_l1_v7
|
bl invalidate_l1_v7
|
||||||
@@ -65,7 +67,7 @@ _tramp_mp_entry:
|
|||||||
#ifdef CONFIG_ARM_V7
|
#ifdef CONFIG_ARM_V7
|
||||||
// ACTRL is implementation defined
|
// ACTRL is implementation defined
|
||||||
mrc p15, 0, r0, c0, c0, 0 // read MIDR
|
mrc p15, 0, r0, c0, c0, 0 // read MIDR
|
||||||
adr r3, .Lactrl_cpuid_a9 // load addr
|
adr r3, .Lactrl_cpuid // load addr
|
||||||
ldm r3, {r1,r2} // load mask + val
|
ldm r3, {r1,r2} // load mask + val
|
||||||
and r0, r1 // apply mask
|
and r0, r1 // apply mask
|
||||||
teq r0, r2 // check value
|
teq r0, r2 // check value
|
||||||
@@ -73,9 +75,11 @@ _tramp_mp_entry:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
mrc p15, 0, r0, c1, c0, 1
|
mrc p15, 0, r0, c1, c0, 1
|
||||||
#ifdef CONFIG_ARM_V7
|
#ifdef CONFIG_ARM_CORTEX_A15
|
||||||
tst r0, #0x40
|
orr r0, r0, #0x40
|
||||||
bne 2f
|
#elif defined CONFIG_ARM_V7
|
||||||
|
tst r0, #0x40
|
||||||
|
bne 2f
|
||||||
orr r0, r0, #0x41
|
orr r0, r0, #0x41
|
||||||
#else
|
#else
|
||||||
orr r0, r0, #0x20
|
orr r0, r0, #0x20
|
||||||
@@ -114,10 +118,20 @@ _tramp_mp_entry:
|
|||||||
.Lmpcore_phys_base:
|
.Lmpcore_phys_base:
|
||||||
.long MPCORE_PHYS_BASE
|
.long MPCORE_PHYS_BASE
|
||||||
|
|
||||||
// only one currently
|
#ifdef CONFIG_ARM_CORTEX_A9
|
||||||
.Lactrl_cpuid_a9:
|
.Lactrl_cpuid:
|
||||||
.long 0xff0ffff0
|
.long 0xff0ffff0
|
||||||
.long 0x410fc090
|
.long 0x410fc090
|
||||||
|
#elif defined CONFIG_ARM_CORTEX_A15
|
||||||
|
.Lactrl_cpuid:
|
||||||
|
.long 0xff0ffff0
|
||||||
|
.long 0x410fc0f0
|
||||||
|
#else
|
||||||
|
.Lactrl_cpuid:
|
||||||
|
.long 0xffffffff
|
||||||
|
.long 0x0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// we run paged now
|
// we run paged now
|
||||||
_tramp_mp_virt:
|
_tramp_mp_virt:
|
||||||
|
|||||||
@@ -124,5 +124,9 @@ IMPLEMENT
|
|||||||
void
|
void
|
||||||
Irq_mgr::set_cpu(Mword irqnum, unsigned cpu) const
|
Irq_mgr::set_cpu(Mword irqnum, unsigned cpu) const
|
||||||
{
|
{
|
||||||
WARNX(Warning, "IRQ%ld: ignoring CPU setting (%d).\n", irqnum, cpu);
|
Irq i = chip(irqnum);
|
||||||
|
if (!i.chip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
i.chip->set_cpu(i.pin, cpu);
|
||||||
}
|
}
|
||||||
|
|||||||
55
kernel/fiasco/src/kern/timer_tick-multi-vector.cpp
Normal file
55
kernel/fiasco/src/kern/timer_tick-multi-vector.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
INTERFACE:
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "per_cpu_data.h"
|
||||||
|
|
||||||
|
EXTENSION class Timer_tick
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Per_cpu<Timer_tick> _glbl_timer;
|
||||||
|
|
||||||
|
Timer_tick()
|
||||||
|
{
|
||||||
|
if (Proc::cpu_id())
|
||||||
|
set_hit(&handler_app);
|
||||||
|
else
|
||||||
|
set_hit(&handler_sys_time);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENTATION:
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
DEFINE_PER_CPU Per_cpu<Timer_tick> Timer_tick::_glbl_timer;
|
||||||
|
|
||||||
|
IMPLEMENT void
|
||||||
|
Timer_tick::setup(unsigned cpu)
|
||||||
|
{
|
||||||
|
if (!allocate_irq(&_glbl_timer.cpu(cpu), Timer::irq()))
|
||||||
|
panic("Could not allocate scheduling IRQ %d\n", Timer::irq());
|
||||||
|
|
||||||
|
_glbl_timer.cpu(cpu).set_mode(Timer::irq_mode());
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT
|
||||||
|
void
|
||||||
|
Timer_tick::enable(unsigned)
|
||||||
|
{
|
||||||
|
_glbl_timer.current().chip()->unmask(_glbl_timer.current().pin());
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT
|
||||||
|
void
|
||||||
|
Timer_tick::disable(unsigned)
|
||||||
|
{
|
||||||
|
_glbl_timer.current().chip()->mask(_glbl_timer.current().pin());
|
||||||
|
}
|
||||||
|
|
||||||
|
PUBLIC inline NEEDS["timer.h"]
|
||||||
|
void
|
||||||
|
Timer_tick::ack()
|
||||||
|
{
|
||||||
|
Timer::acknowledge();
|
||||||
|
Irq_base::ack();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user