first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
#include <arch.h>
|
||||
#include <arch/arm/arm.h>
|
||||
#include <debug.h>
|
||||
#include <drivers/a5iop/a5iop.h>
|
||||
#include <platform.h>
|
||||
#include <platform/int.h>
|
||||
#include <platform/timer.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/task.h>
|
||||
|
||||
/*
|
||||
* Cache control
|
||||
*/
|
||||
void
|
||||
a5iop_cache_operation(int operation, void *address, u_int32_t length)
|
||||
{
|
||||
uint32_t actual_base, lines, extra;
|
||||
|
||||
if (unlikely(length == 0)) {
|
||||
enter_critical_section();
|
||||
if (operation & CACHE_CLEAN)
|
||||
arm_clean_dcache();
|
||||
if (operation & CACHE_INVALIDATE)
|
||||
arm_invalidate_dcache();
|
||||
exit_critical_section();
|
||||
|
||||
/* on the panic path, disable the cache? XXX */
|
||||
if (operation & CACHE_PANIC) { }
|
||||
} else {
|
||||
actual_base = (uint32_t)address;
|
||||
ASSERT((actual_base & ~(CPU_CACHELINE_SIZE-1)) == actual_base);
|
||||
ASSERT((length % CPU_CACHELINE_SIZE) == 0);
|
||||
|
||||
lines = length >> CPU_CACHELINE_SHIFT;
|
||||
ASSERT(lines > 0);
|
||||
|
||||
extra = lines & 7;
|
||||
lines -= extra;
|
||||
|
||||
/* perform loop unrolling to optimize multi-line operations rdar://problem/6722268 */
|
||||
if (operation & (CACHE_CLEAN | CACHE_INVALIDATE)) {
|
||||
switch (extra) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
arm_clean_invalidate_dcache_line(actual_base);
|
||||
break;
|
||||
case 2:
|
||||
arm_clean_invalidate_dcache_line_2(actual_base);
|
||||
break;
|
||||
case 3:
|
||||
arm_clean_invalidate_dcache_line_3(actual_base);
|
||||
break;
|
||||
case 4:
|
||||
arm_clean_invalidate_dcache_line_4(actual_base);
|
||||
break;
|
||||
case 5:
|
||||
arm_clean_invalidate_dcache_line_5(actual_base);
|
||||
break;
|
||||
case 6:
|
||||
arm_clean_invalidate_dcache_line_6(actual_base);
|
||||
break;
|
||||
case 7:
|
||||
arm_clean_invalidate_dcache_line_7(actual_base);
|
||||
break;
|
||||
}
|
||||
actual_base += CPU_CACHELINE_SIZE * extra;
|
||||
|
||||
while (lines) {
|
||||
arm_clean_invalidate_dcache_line_8(actual_base);
|
||||
lines -= 8;
|
||||
actual_base += CPU_CACHELINE_SIZE * 8;
|
||||
}
|
||||
} else if (operation & CACHE_CLEAN) {
|
||||
switch (extra) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
arm_clean_dcache_line(actual_base);
|
||||
break;
|
||||
case 2:
|
||||
arm_clean_dcache_line_2(actual_base);
|
||||
break;
|
||||
case 3:
|
||||
arm_clean_dcache_line_3(actual_base);
|
||||
break;
|
||||
case 4:
|
||||
arm_clean_dcache_line_4(actual_base);
|
||||
break;
|
||||
case 5:
|
||||
arm_clean_dcache_line_5(actual_base);
|
||||
break;
|
||||
case 6:
|
||||
arm_clean_dcache_line_6(actual_base);
|
||||
break;
|
||||
case 7:
|
||||
arm_clean_dcache_line_7(actual_base);
|
||||
break;
|
||||
}
|
||||
actual_base += CPU_CACHELINE_SIZE * extra;
|
||||
|
||||
while (lines) {
|
||||
arm_clean_dcache_line_8(actual_base);
|
||||
lines -= 8;
|
||||
actual_base += CPU_CACHELINE_SIZE * 8;
|
||||
}
|
||||
} else {// operation & CACHE_INVALIDATE
|
||||
switch (extra) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
arm_invalidate_dcache_line(actual_base);
|
||||
break;
|
||||
case 2:
|
||||
arm_invalidate_dcache_line_2(actual_base);
|
||||
break;
|
||||
case 3:
|
||||
arm_invalidate_dcache_line_3(actual_base);
|
||||
break;
|
||||
case 4:
|
||||
arm_invalidate_dcache_line_4(actual_base);
|
||||
break;
|
||||
case 5:
|
||||
arm_invalidate_dcache_line_5(actual_base);
|
||||
break;
|
||||
case 6:
|
||||
arm_invalidate_dcache_line_6(actual_base);
|
||||
break;
|
||||
case 7:
|
||||
arm_invalidate_dcache_line_7(actual_base);
|
||||
break;
|
||||
}
|
||||
actual_base += CPU_CACHELINE_SIZE * extra;
|
||||
|
||||
while (lines) {
|
||||
arm_invalidate_dcache_line_8(actual_base);
|
||||
lines -= 8;
|
||||
actual_base += CPU_CACHELINE_SIZE * 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SUPPORT_SLEEP
|
||||
static struct task *sleeping_task;
|
||||
static u_int32_t idle_sleep;
|
||||
static u_int32_t powergate_cnt, powerwake_cnt, powerfall_cnt;
|
||||
static u_int32_t suspend_cnt, wake_cnt;
|
||||
static u_int64_t sleep_stamp, wake_stamp;
|
||||
extern u_int32_t arch_sleep_magic;
|
||||
|
||||
void
|
||||
a5iop_sleep(u_int32_t going_idle)
|
||||
{
|
||||
idle_sleep = going_idle;
|
||||
if (idle_sleep)
|
||||
powergate_cnt++;
|
||||
else
|
||||
suspend_cnt++;
|
||||
|
||||
/* disable interrupts; this is matched in the wake path */
|
||||
enter_critical_section();
|
||||
|
||||
/* we are the sleeping task */
|
||||
sleeping_task = task_get_current_task();
|
||||
|
||||
sleep_stamp = timer_get_ticks();
|
||||
|
||||
/* fool the upcoming test on the sleep path */
|
||||
arch_sleep_magic = SLEEP_MAGIC_NOT_ASLEEP;
|
||||
|
||||
/* save our current context - on wake we will return from this call */
|
||||
arch_task_context_switch(&sleeping_task->arch, &sleeping_task->arch);
|
||||
|
||||
/* if we are on the wake path, go back */
|
||||
if (SLEEP_MAGIC_WAKEY_WAKEY == arch_sleep_magic) {
|
||||
RELEASE_ASSERT(powergate_cnt == powerfall_cnt + powerwake_cnt);
|
||||
RELEASE_ASSERT(suspend_cnt == wake_cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
/* flip the switch and wait for us to go to sleep */
|
||||
arch_sleep_magic = SLEEP_MAGIC_WAKEY_WAKEY;
|
||||
|
||||
/* Flush and invalidate the the entire dcache
|
||||
* Don't call a5iop_cache_operation directly because the
|
||||
* irq_disable count won't get flushed */
|
||||
arm_clean_dcache();
|
||||
|
||||
/* Use WFI to fully quiesce */
|
||||
arch_halt();
|
||||
|
||||
if (idle_sleep) {
|
||||
/* It's possible to fall through the WFI without
|
||||
* power-gating, so carry on in that case. */
|
||||
powerfall_cnt++;
|
||||
exit_critical_section();
|
||||
} else {
|
||||
/* On the sleep/suspend path, it's not acceptible to
|
||||
* return from this routine. We don't expect to fall
|
||||
* through the WFI but better safe than sorry. */
|
||||
while (1) arch_halt();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
platform_wakeup(void)
|
||||
{
|
||||
/* Reestablish the correct CPU configuration */
|
||||
arch_cpu_init(true);
|
||||
|
||||
wake_stamp = timer_get_ticks();
|
||||
|
||||
if (idle_sleep) {
|
||||
/* Waking from idle power-gating; timer and interrupt
|
||||
* state is intact; we just need to pop a level of IRQ
|
||||
* disable and start running. */
|
||||
powerwake_cnt++;
|
||||
exit_critical_section();
|
||||
} else {
|
||||
wake_cnt++;
|
||||
platform_early_init();
|
||||
}
|
||||
/* There should be a better abstracted way to enable NMI <rdar://problem/8269765> */
|
||||
arm_enable_fiqs();
|
||||
|
||||
/* kick the callout system to re-evaluate deadlines */
|
||||
callout_reset_deadline();
|
||||
|
||||
/* and switch back to the context that went to sleep */
|
||||
arch_task_context_restore(&sleeping_task->arch);
|
||||
|
||||
panic("arch_task_context_restore didn't");
|
||||
}
|
||||
|
||||
#endif /* SUPPORT_SLEEP */
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#ifndef __A5IOP_H
|
||||
#define __A5IOP_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern void a5iop_init(void);
|
||||
extern void a5iop_cache_operation(int operation, void *address, u_int32_t length);
|
||||
extern void a5iop_sleep(u_int32_t going_idle);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
ALL_OBJS += $(LOCAL_DIR)/a5iop.o
|
||||
|
||||
GLOBAL_INCLUDES += $(LOCAL_DIR)/include
|
||||
Reference in new issue
Block a user