mirror of https://gitee.com/openkylin/linux.git
Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
This commit is contained in:
commit
af6f5e3247
|
@ -252,8 +252,7 @@ in a tasks processor placement.
|
|||
There is an exception to the above. If hotplug funtionality is used
|
||||
to remove all the CPUs that are currently assigned to a cpuset,
|
||||
then the kernel will automatically update the cpus_allowed of all
|
||||
tasks attached to CPUs in that cpuset with the online CPUs of the
|
||||
nearest parent cpuset that still has some CPUs online. When memory
|
||||
tasks attached to CPUs in that cpuset to allow all CPUs. When memory
|
||||
hotplug functionality for removing Memory Nodes is available, a
|
||||
similar exception is expected to apply there as well. In general,
|
||||
the kernel prefers to violate cpuset placement, over starving a task
|
||||
|
|
|
@ -25,6 +25,9 @@ APICs
|
|||
|
||||
noapictimer Don't set up the APIC timer
|
||||
|
||||
no_timer_check Don't check the IO-APIC timer. This can work around
|
||||
problems with incorrect timer initialization on some boards.
|
||||
|
||||
Early Console
|
||||
|
||||
syntax: earlyprintk=vga
|
||||
|
|
|
@ -1023,8 +1023,8 @@ W: http://www.ia64-linux.org/
|
|||
S: Maintained
|
||||
|
||||
SN-IA64 (Itanium) SUB-PLATFORM
|
||||
P: Jesse Barnes
|
||||
M: jbarnes@sgi.com
|
||||
P: Greg Edwards
|
||||
M: edwardsg@sgi.com
|
||||
L: linux-altix@sgi.com
|
||||
L: linux-ia64@vger.kernel.org
|
||||
W: http://www.sgi.com/altix
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 12
|
||||
EXTRAVERSION =-rc4
|
||||
EXTRAVERSION =-rc5
|
||||
NAME=Woozy Numbat
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -1163,7 +1163,7 @@ config PCI_DIRECT
|
|||
|
||||
config PCI_MMCONFIG
|
||||
bool
|
||||
depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI))
|
||||
depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
|
||||
select ACPI_BOOT
|
||||
default y
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ static void __init init_amd(struct cpuinfo_x86 *c)
|
|||
c->x86_num_cores = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_SMP
|
||||
#ifdef CONFIG_X86_HT
|
||||
/*
|
||||
* On a AMD dual core setup the lower bits of the APIC id
|
||||
* distingush the cores. Assumes number of cores is a power
|
||||
|
@ -203,8 +203,11 @@ static void __init init_amd(struct cpuinfo_x86 *c)
|
|||
*/
|
||||
if (c->x86_num_cores > 1) {
|
||||
int cpu = smp_processor_id();
|
||||
/* Fix up the APIC ID following AMD specifications. */
|
||||
cpu_core_id[cpu] >>= hweight32(c->x86_num_cores - 1);
|
||||
unsigned bits = 0;
|
||||
while ((1 << bits) < c->x86_num_cores)
|
||||
bits++;
|
||||
cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
|
||||
phys_proc_id[cpu] >>= bits;
|
||||
printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
|
||||
cpu, c->x86_num_cores, cpu_core_id[cpu]);
|
||||
}
|
||||
|
|
|
@ -244,11 +244,8 @@ static void __init early_cpu_detect(void)
|
|||
|
||||
early_intel_workaround(c);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#ifdef CONFIG_X86_HT
|
||||
phys_proc_id[smp_processor_id()] =
|
||||
#endif
|
||||
cpu_core_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
|
||||
phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ struct _cpuid4_info {
|
|||
};
|
||||
|
||||
#define MAX_CACHE_LEAVES 4
|
||||
static unsigned short __devinitdata num_cache_leaves;
|
||||
static unsigned short num_cache_leaves;
|
||||
|
||||
static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
|
||||
{
|
||||
|
|
|
@ -888,6 +888,7 @@ void *xquad_portio;
|
|||
|
||||
cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
|
||||
cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
|
||||
EXPORT_SYMBOL(cpu_core_map);
|
||||
|
||||
static void __init smp_boot_cpus(unsigned int max_cpus)
|
||||
{
|
||||
|
@ -1073,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
|
|||
cpu_set(cpu, cpu_sibling_map[cpu]);
|
||||
}
|
||||
|
||||
if (siblings != smp_num_siblings)
|
||||
if (siblings != smp_num_siblings) {
|
||||
printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
|
||||
smp_num_siblings = siblings;
|
||||
}
|
||||
|
||||
if (c->x86_num_cores > 1) {
|
||||
for (i = 0; i < NR_CPUS; i++) {
|
||||
|
|
|
@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
|
|||
static void vic_enable_cpi(void);
|
||||
static void do_boot_cpu(__u8 cpuid);
|
||||
static void do_quad_bootstrap(void);
|
||||
static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
|
||||
|
||||
int hard_smp_processor_id(void);
|
||||
|
||||
|
@ -125,6 +124,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
irq_enter();
|
||||
smp_local_timer_interrupt(regs);
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
static inline void
|
||||
send_one_CPI(__u8 cpu, __u8 cpi)
|
||||
{
|
||||
|
@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
|
|||
smp_local_timer_interrupt(regs);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
irq_enter();
|
||||
smp_local_timer_interrupt(regs);
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
/* local (per CPU) timer interrupt. It does both profiling and
|
||||
* process statistics/rescheduling.
|
||||
*
|
||||
|
|
|
@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr)
|
|||
addr < phys_to_virt(ISA_END_ADDRESS))
|
||||
return;
|
||||
|
||||
p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
|
||||
write_lock(&vmlist_lock);
|
||||
p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
|
||||
if (!p) {
|
||||
printk("__iounmap: bad address %p\n", addr);
|
||||
return;
|
||||
printk("iounmap: bad address %p\n", addr);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
|
||||
/* p->size includes the guard page, but cpa doesn't like that */
|
||||
change_page_attr(virt_to_page(__va(p->phys_addr)),
|
||||
p->size >> PAGE_SHIFT,
|
||||
PAGE_KERNEL);
|
||||
global_flush_tlb();
|
||||
}
|
||||
out_unlock:
|
||||
write_unlock(&vmlist_lock);
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq)
|
|||
static int pirq_enable_irq(struct pci_dev *dev)
|
||||
{
|
||||
u8 pin;
|
||||
extern int via_interrupt_line_quirk;
|
||||
struct pci_dev *temp_dev;
|
||||
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
|
||||
|
@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
|||
printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
|
||||
'A' + pin, pci_name(dev), msg);
|
||||
}
|
||||
/* VIA bridges use interrupt line for apic/pci steering across
|
||||
the V-Link */
|
||||
else if (via_interrupt_line_quirk)
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1182,7 +1182,7 @@ ENTRY(notify_resume_user)
|
|||
;;
|
||||
(pNonSys) mov out2=0 // out2==0 => not a syscall
|
||||
.fframe 16
|
||||
.spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!)
|
||||
.spillsp ar.unat, 16
|
||||
st8 [sp]=r9,-16 // allocate space for ar.unat and save it
|
||||
st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch
|
||||
.body
|
||||
|
@ -1208,7 +1208,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend)
|
|||
adds out2=8,sp // out2=&sigscratch->ar_pfs
|
||||
;;
|
||||
.fframe 16
|
||||
.spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!)
|
||||
.spillsp ar.unat, 16
|
||||
st8 [sp]=r9,-16 // allocate space for ar.unat and save it
|
||||
st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch
|
||||
.body
|
||||
|
|
|
@ -1390,8 +1390,7 @@ ia64_mca_init(void)
|
|||
register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/* Setup the CPEI/P vector and handler */
|
||||
cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
|
||||
/* Setup the CPEI/P handler */
|
||||
register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
|
||||
#endif
|
||||
|
||||
|
@ -1436,6 +1435,7 @@ ia64_mca_late_init(void)
|
|||
|
||||
#ifdef CONFIG_ACPI
|
||||
/* Setup the CPEI/P vector and handler */
|
||||
cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
|
||||
init_timer(&cpe_poll_timer);
|
||||
cpe_poll_timer.function = ia64_mca_cpe_poll;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \
|
||||
(pKStk) ld8 r3 = [r3];; \
|
||||
(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \
|
||||
(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \
|
||||
(pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \
|
||||
(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \
|
||||
(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \
|
||||
;; \
|
||||
|
@ -50,7 +50,6 @@
|
|||
(pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \
|
||||
(pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \
|
||||
;; \
|
||||
(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \
|
||||
(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \
|
||||
;; \
|
||||
(pUStk) mov r18=ar.bsp; \
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* Version Perfmon-2.x is a rewrite of perfmon-1.x
|
||||
* by Stephane Eranian, Hewlett Packard Co.
|
||||
*
|
||||
* Copyright (C) 1999-2003, 2005 Hewlett Packard Co
|
||||
* Copyright (C) 1999-2005 Hewlett Packard Co
|
||||
* Stephane Eranian <eranian@hpl.hp.com>
|
||||
* David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
*
|
||||
|
@ -497,6 +497,9 @@ typedef struct {
|
|||
static pfm_stats_t pfm_stats[NR_CPUS];
|
||||
static pfm_session_t pfm_sessions; /* global sessions information */
|
||||
|
||||
static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED;
|
||||
static pfm_intr_handler_desc_t *pfm_alt_intr_handler;
|
||||
|
||||
static struct proc_dir_entry *perfmon_dir;
|
||||
static pfm_uuid_t pfm_null_uuid = {0,};
|
||||
|
||||
|
@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info);
|
|||
DEFINE_PER_CPU(struct task_struct *, pmu_owner);
|
||||
DEFINE_PER_CPU(pfm_context_t *, pmu_ctx);
|
||||
DEFINE_PER_CPU(unsigned long, pmu_activation_number);
|
||||
EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info);
|
||||
|
||||
|
||||
/* forward declaration */
|
||||
|
@ -1325,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
|
|||
error_conflict:
|
||||
DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
|
||||
pfm_sessions.pfs_sys_session[cpu]->pid,
|
||||
smp_processor_id()));
|
||||
cpu));
|
||||
abort:
|
||||
UNLOCK_PFS(flags);
|
||||
|
||||
|
@ -5555,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
|
|||
int ret;
|
||||
|
||||
this_cpu = get_cpu();
|
||||
min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
|
||||
max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
|
||||
if (likely(!pfm_alt_intr_handler)) {
|
||||
min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
|
||||
max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
|
||||
|
||||
start_cycles = ia64_get_itc();
|
||||
start_cycles = ia64_get_itc();
|
||||
|
||||
ret = pfm_do_interrupt_handler(irq, arg, regs);
|
||||
ret = pfm_do_interrupt_handler(irq, arg, regs);
|
||||
|
||||
total_cycles = ia64_get_itc();
|
||||
total_cycles = ia64_get_itc();
|
||||
|
||||
/*
|
||||
* don't measure spurious interrupts
|
||||
*/
|
||||
if (likely(ret == 0)) {
|
||||
total_cycles -= start_cycles;
|
||||
/*
|
||||
* don't measure spurious interrupts
|
||||
*/
|
||||
if (likely(ret == 0)) {
|
||||
total_cycles -= start_cycles;
|
||||
|
||||
if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
|
||||
if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
|
||||
if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
|
||||
if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
|
||||
|
||||
pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
|
||||
pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
|
||||
}
|
||||
}
|
||||
else {
|
||||
(*pfm_alt_intr_handler->handler)(irq, arg, regs);
|
||||
}
|
||||
|
||||
put_cpu_no_resched();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -6425,6 +6435,141 @@ static struct irqaction perfmon_irqaction = {
|
|||
.name = "perfmon"
|
||||
};
|
||||
|
||||
static void
|
||||
pfm_alt_save_pmu_state(void *data)
|
||||
{
|
||||
struct pt_regs *regs;
|
||||
|
||||
regs = ia64_task_regs(current);
|
||||
|
||||
DPRINT(("called\n"));
|
||||
|
||||
/*
|
||||
* should not be necessary but
|
||||
* let's take not risk
|
||||
*/
|
||||
pfm_clear_psr_up();
|
||||
pfm_clear_psr_pp();
|
||||
ia64_psr(regs)->pp = 0;
|
||||
|
||||
/*
|
||||
* This call is required
|
||||
* May cause a spurious interrupt on some processors
|
||||
*/
|
||||
pfm_freeze_pmu();
|
||||
|
||||
ia64_srlz_d();
|
||||
}
|
||||
|
||||
void
|
||||
pfm_alt_restore_pmu_state(void *data)
|
||||
{
|
||||
struct pt_regs *regs;
|
||||
|
||||
regs = ia64_task_regs(current);
|
||||
|
||||
DPRINT(("called\n"));
|
||||
|
||||
/*
|
||||
* put PMU back in state expected
|
||||
* by perfmon
|
||||
*/
|
||||
pfm_clear_psr_up();
|
||||
pfm_clear_psr_pp();
|
||||
ia64_psr(regs)->pp = 0;
|
||||
|
||||
/*
|
||||
* perfmon runs with PMU unfrozen at all times
|
||||
*/
|
||||
pfm_unfreeze_pmu();
|
||||
|
||||
ia64_srlz_d();
|
||||
}
|
||||
|
||||
int
|
||||
pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
|
||||
{
|
||||
int ret, i;
|
||||
int reserve_cpu;
|
||||
|
||||
/* some sanity checks */
|
||||
if (hdl == NULL || hdl->handler == NULL) return -EINVAL;
|
||||
|
||||
/* do the easy test first */
|
||||
if (pfm_alt_intr_handler) return -EBUSY;
|
||||
|
||||
/* one at a time in the install or remove, just fail the others */
|
||||
if (!spin_trylock(&pfm_alt_install_check)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* reserve our session */
|
||||
for_each_online_cpu(reserve_cpu) {
|
||||
ret = pfm_reserve_session(NULL, 1, reserve_cpu);
|
||||
if (ret) goto cleanup_reserve;
|
||||
}
|
||||
|
||||
/* save the current system wide pmu states */
|
||||
ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
|
||||
if (ret) {
|
||||
DPRINT(("on_each_cpu() failed: %d\n", ret));
|
||||
goto cleanup_reserve;
|
||||
}
|
||||
|
||||
/* officially change to the alternate interrupt handler */
|
||||
pfm_alt_intr_handler = hdl;
|
||||
|
||||
spin_unlock(&pfm_alt_install_check);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup_reserve:
|
||||
for_each_online_cpu(i) {
|
||||
/* don't unreserve more than we reserved */
|
||||
if (i >= reserve_cpu) break;
|
||||
|
||||
pfm_unreserve_session(NULL, 1, i);
|
||||
}
|
||||
|
||||
spin_unlock(&pfm_alt_install_check);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt);
|
||||
|
||||
int
|
||||
pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (hdl == NULL) return -EINVAL;
|
||||
|
||||
/* cannot remove someone else's handler! */
|
||||
if (pfm_alt_intr_handler != hdl) return -EINVAL;
|
||||
|
||||
/* one at a time in the install or remove, just fail the others */
|
||||
if (!spin_trylock(&pfm_alt_install_check)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
pfm_alt_intr_handler = NULL;
|
||||
|
||||
ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1);
|
||||
if (ret) {
|
||||
DPRINT(("on_each_cpu() failed: %d\n", ret));
|
||||
}
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
pfm_unreserve_session(NULL, 1, i);
|
||||
}
|
||||
|
||||
spin_unlock(&pfm_alt_install_check);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt);
|
||||
|
||||
/*
|
||||
* perfmon initialization routine, called from the initcall() table
|
||||
*/
|
||||
|
|
|
@ -692,16 +692,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt,
|
|||
unsigned long cfm)
|
||||
{
|
||||
struct unw_frame_info info, prev_info;
|
||||
unsigned long ip, pr;
|
||||
unsigned long ip, sp, pr;
|
||||
|
||||
unw_init_from_blocked_task(&info, child);
|
||||
while (1) {
|
||||
prev_info = info;
|
||||
if (unw_unwind(&info) < 0)
|
||||
return;
|
||||
if (unw_get_rp(&info, &ip) < 0)
|
||||
|
||||
unw_get_sp(&info, &sp);
|
||||
if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
|
||||
< IA64_PT_REGS_SIZE) {
|
||||
dprintk("ptrace.%s: ran off the top of the kernel "
|
||||
"stack\n", __FUNCTION__);
|
||||
return;
|
||||
if (ip < FIXADDR_USER_END)
|
||||
}
|
||||
if (unw_get_pr (&prev_info, &pr) < 0) {
|
||||
unw_get_rp(&prev_info, &ip);
|
||||
dprintk("ptrace.%s: failed to read "
|
||||
"predicate register (ip=0x%lx)\n",
|
||||
__FUNCTION__, ip);
|
||||
return;
|
||||
}
|
||||
if (unw_is_intr_frame(&info)
|
||||
&& (pr & (1UL << PRED_USER_STACK)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -624,7 +624,7 @@ static struct {
|
|||
__u16 thread_id;
|
||||
__u16 proc_fixed_addr;
|
||||
__u8 valid;
|
||||
}mt_info[NR_CPUS] __devinit;
|
||||
} mt_info[NR_CPUS] __devinitdata;
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static inline void
|
||||
|
|
|
@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A zero mmap always succeeds in Linux, independent of whether or not the
|
||||
* remaining arguments are valid.
|
||||
*/
|
||||
if (len == 0)
|
||||
goto out;
|
||||
|
||||
/* Careful about overflows.. */
|
||||
len = PAGE_ALIGN(len);
|
||||
if (!len || len > TASK_SIZE) {
|
||||
|
|
|
@ -271,6 +271,8 @@ void __init sn_setup(char **cmdline_p)
|
|||
int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
|
||||
extern void sn_cpu_init(void);
|
||||
|
||||
ia64_sn_plat_set_error_handling_features();
|
||||
|
||||
/*
|
||||
* If the generic code has enabled vga console support - lets
|
||||
* get rid of it again. This is a kludge for the fact that ACPI
|
||||
|
|
|
@ -1143,12 +1143,12 @@ config PCI_QSPAN
|
|||
|
||||
config PCI_8260
|
||||
bool
|
||||
depends on PCI && 8260 && !8272
|
||||
depends on PCI && 8260
|
||||
default y
|
||||
|
||||
config 8260_PCI9
|
||||
bool " Enable workaround for MPC826x erratum PCI 9"
|
||||
depends on PCI_8260
|
||||
depends on PCI_8260 && !ADS8272
|
||||
default y
|
||||
|
||||
choice
|
||||
|
|
|
@ -22,7 +22,8 @@ targets += uImage
|
|||
$(obj)/uImage: $(obj)/vmlinux.gz
|
||||
$(Q)rm -f $@
|
||||
$(call if_changed,uimage)
|
||||
@echo ' Image: $@' $(if $(wildcard $@),'is ready','not made')
|
||||
@echo -n ' Image: $@ '
|
||||
@if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
|
||||
|
||||
# Files generated that shall be removed upon make clean
|
||||
clean-files := sImage vmapus vmlinux* miboot* zImage* uImage
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.11-rc1
|
||||
# Thu Jan 20 01:25:35 2005
|
||||
# Linux kernel version: 2.6.12-rc4
|
||||
# Tue May 17 11:56:01 2005
|
||||
#
|
||||
CONFIG_MMU=y
|
||||
CONFIG_GENERIC_HARDIRQS=y
|
||||
|
@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
|
|||
CONFIG_PPC=y
|
||||
CONFIG_PPC32=y
|
||||
CONFIG_GENERIC_NVRAM=y
|
||||
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
|
@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
|
|||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_CLEAN_COMPILE=y
|
||||
CONFIG_BROKEN_ON_SMP=y
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
|
||||
#
|
||||
# General setup
|
||||
|
@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y
|
|||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
CONFIG_SYSCTL=y
|
||||
# CONFIG_AUDIT is not set
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
# CONFIG_HOTPLUG is not set
|
||||
CONFIG_KOBJECT_UEVENT=y
|
||||
# CONFIG_IKCONFIG is not set
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_KALLSYMS is not set
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_BUG=y
|
||||
CONFIG_BASE_FULL=y
|
||||
CONFIG_FUTEX=y
|
||||
# CONFIG_EPOLL is not set
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
|
@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0
|
|||
CONFIG_CC_ALIGN_LOOPS=0
|
||||
CONFIG_CC_ALIGN_JUMPS=0
|
||||
# CONFIG_TINY_SHMEM is not set
|
||||
CONFIG_BASE_SMALL=0
|
||||
|
||||
#
|
||||
# Loadable module support
|
||||
|
@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0
|
|||
CONFIG_E500=y
|
||||
CONFIG_BOOKE=y
|
||||
CONFIG_FSL_BOOKE=y
|
||||
# CONFIG_PHYS_64BIT is not set
|
||||
CONFIG_SPE=y
|
||||
CONFIG_MATH_EMULATION=y
|
||||
# CONFIG_CPU_FREQ is not set
|
||||
CONFIG_PPC_GEN550=y
|
||||
# CONFIG_PM is not set
|
||||
CONFIG_85xx=y
|
||||
CONFIG_PPC_INDIRECT_PCI_BE=y
|
||||
|
||||
|
@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y
|
|||
CONFIG_MPC8555_CDS=y
|
||||
# CONFIG_MPC8560_ADS is not set
|
||||
# CONFIG_SBC8560 is not set
|
||||
# CONFIG_STX_GP3 is not set
|
||||
CONFIG_MPC8555=y
|
||||
CONFIG_85xx_PCI2=y
|
||||
|
||||
|
@ -90,6 +98,7 @@ CONFIG_CPM2=y
|
|||
CONFIG_BINFMT_ELF=y
|
||||
# CONFIG_BINFMT_MISC is not set
|
||||
# CONFIG_CMDLINE_BOOL is not set
|
||||
CONFIG_ISA_DMA_API=y
|
||||
|
||||
#
|
||||
# Bus options
|
||||
|
@ -104,10 +113,6 @@ CONFIG_PCI_NAMES=y
|
|||
#
|
||||
# CONFIG_PCCARD is not set
|
||||
|
||||
#
|
||||
# PC-card bridges
|
||||
#
|
||||
|
||||
#
|
||||
# Advanced setup
|
||||
#
|
||||
|
@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y
|
|||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
# CONFIG_IDE is not set
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDE=y
|
||||
|
||||
#
|
||||
# Please see Documentation/ide.txt for help/info on IDE drives
|
||||
#
|
||||
# CONFIG_BLK_DEV_IDE_SATA is not set
|
||||
CONFIG_BLK_DEV_IDEDISK=y
|
||||
# CONFIG_IDEDISK_MULTI_MODE is not set
|
||||
# CONFIG_BLK_DEV_IDECD is not set
|
||||
# CONFIG_BLK_DEV_IDETAPE is not set
|
||||
# CONFIG_BLK_DEV_IDEFLOPPY is not set
|
||||
# CONFIG_IDE_TASK_IOCTL is not set
|
||||
|
||||
#
|
||||
# IDE chipset support/bugfixes
|
||||
#
|
||||
CONFIG_IDE_GENERIC=y
|
||||
CONFIG_BLK_DEV_IDEPCI=y
|
||||
CONFIG_IDEPCI_SHARE_IRQ=y
|
||||
# CONFIG_BLK_DEV_OFFBOARD is not set
|
||||
CONFIG_BLK_DEV_GENERIC=y
|
||||
# CONFIG_BLK_DEV_OPTI621 is not set
|
||||
# CONFIG_BLK_DEV_SL82C105 is not set
|
||||
CONFIG_BLK_DEV_IDEDMA_PCI=y
|
||||
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
|
||||
CONFIG_IDEDMA_PCI_AUTO=y
|
||||
# CONFIG_IDEDMA_ONLYDISK is not set
|
||||
# CONFIG_BLK_DEV_AEC62XX is not set
|
||||
# CONFIG_BLK_DEV_ALI15X3 is not set
|
||||
# CONFIG_BLK_DEV_AMD74XX is not set
|
||||
# CONFIG_BLK_DEV_CMD64X is not set
|
||||
# CONFIG_BLK_DEV_TRIFLEX is not set
|
||||
# CONFIG_BLK_DEV_CY82C693 is not set
|
||||
# CONFIG_BLK_DEV_CS5520 is not set
|
||||
# CONFIG_BLK_DEV_CS5530 is not set
|
||||
# CONFIG_BLK_DEV_HPT34X is not set
|
||||
# CONFIG_BLK_DEV_HPT366 is not set
|
||||
# CONFIG_BLK_DEV_SC1200 is not set
|
||||
# CONFIG_BLK_DEV_PIIX is not set
|
||||
# CONFIG_BLK_DEV_NS87415 is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
|
||||
# CONFIG_BLK_DEV_SVWKS is not set
|
||||
# CONFIG_BLK_DEV_SIIMAGE is not set
|
||||
# CONFIG_BLK_DEV_SLC90E66 is not set
|
||||
# CONFIG_BLK_DEV_TRM290 is not set
|
||||
CONFIG_BLK_DEV_VIA82CXXX=y
|
||||
# CONFIG_IDE_ARM is not set
|
||||
CONFIG_BLK_DEV_IDEDMA=y
|
||||
# CONFIG_IDEDMA_IVB is not set
|
||||
CONFIG_IDEDMA_AUTO=y
|
||||
# CONFIG_BLK_DEV_HD is not set
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
|
@ -220,7 +277,6 @@ CONFIG_NET=y
|
|||
#
|
||||
CONFIG_PACKET=y
|
||||
# CONFIG_PACKET_MMAP is not set
|
||||
# CONFIG_NETLINK_DEV is not set
|
||||
CONFIG_UNIX=y
|
||||
# CONFIG_NET_KEY is not set
|
||||
CONFIG_INET=y
|
||||
|
@ -369,14 +425,6 @@ CONFIG_INPUT=y
|
|||
# CONFIG_INPUT_EVDEV is not set
|
||||
# CONFIG_INPUT_EVBUG is not set
|
||||
|
||||
#
|
||||
# Input I/O drivers
|
||||
#
|
||||
# CONFIG_GAMEPORT is not set
|
||||
CONFIG_SOUND_GAMEPORT=y
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_SERIO_I8042 is not set
|
||||
|
||||
#
|
||||
# Input Device Drivers
|
||||
#
|
||||
|
@ -386,6 +434,13 @@ CONFIG_SOUND_GAMEPORT=y
|
|||
# CONFIG_INPUT_TOUCHSCREEN is not set
|
||||
# CONFIG_INPUT_MISC is not set
|
||||
|
||||
#
|
||||
# Hardware I/O ports
|
||||
#
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_GAMEPORT is not set
|
||||
CONFIG_SOUND_GAMEPORT=y
|
||||
|
||||
#
|
||||
# Character devices
|
||||
#
|
||||
|
@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
|
|||
CONFIG_SERIAL_CORE=y
|
||||
CONFIG_SERIAL_CORE_CONSOLE=y
|
||||
# CONFIG_SERIAL_CPM is not set
|
||||
# CONFIG_SERIAL_JSM is not set
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
CONFIG_LEGACY_PTYS=y
|
||||
CONFIG_LEGACY_PTY_COUNT=256
|
||||
|
@ -433,6 +489,11 @@ CONFIG_GEN_RTC=y
|
|||
# CONFIG_DRM is not set
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
|
||||
#
|
||||
# TPM devices
|
||||
#
|
||||
# CONFIG_TCG_TPM is not set
|
||||
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
|
@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y
|
|||
# CONFIG_I2C_AMD8111 is not set
|
||||
# CONFIG_I2C_I801 is not set
|
||||
# CONFIG_I2C_I810 is not set
|
||||
# CONFIG_I2C_PIIX4 is not set
|
||||
# CONFIG_I2C_ISA is not set
|
||||
CONFIG_I2C_MPC=y
|
||||
# CONFIG_I2C_NFORCE2 is not set
|
||||
# CONFIG_I2C_PARPORT_LIGHT is not set
|
||||
# CONFIG_I2C_PIIX4 is not set
|
||||
# CONFIG_I2C_PROSAVAGE is not set
|
||||
# CONFIG_I2C_SAVAGE4 is not set
|
||||
# CONFIG_SCx200_ACB is not set
|
||||
|
@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y
|
|||
# CONFIG_SENSORS_ASB100 is not set
|
||||
# CONFIG_SENSORS_DS1621 is not set
|
||||
# CONFIG_SENSORS_FSCHER is not set
|
||||
# CONFIG_SENSORS_FSCPOS is not set
|
||||
# CONFIG_SENSORS_GL518SM is not set
|
||||
# CONFIG_SENSORS_GL520SM is not set
|
||||
# CONFIG_SENSORS_IT87 is not set
|
||||
# CONFIG_SENSORS_LM63 is not set
|
||||
# CONFIG_SENSORS_LM75 is not set
|
||||
|
@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y
|
|||
# CONFIG_SENSORS_LM85 is not set
|
||||
# CONFIG_SENSORS_LM87 is not set
|
||||
# CONFIG_SENSORS_LM90 is not set
|
||||
# CONFIG_SENSORS_LM92 is not set
|
||||
# CONFIG_SENSORS_MAX1619 is not set
|
||||
# CONFIG_SENSORS_PC87360 is not set
|
||||
# CONFIG_SENSORS_SMSC47B397 is not set
|
||||
# CONFIG_SENSORS_SIS5595 is not set
|
||||
# CONFIG_SENSORS_SMSC47M1 is not set
|
||||
# CONFIG_SENSORS_VIA686A is not set
|
||||
# CONFIG_SENSORS_W83781D is not set
|
||||
|
@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y
|
|||
#
|
||||
# Other I2C Chip support
|
||||
#
|
||||
# CONFIG_SENSORS_DS1337 is not set
|
||||
# CONFIG_SENSORS_EEPROM is not set
|
||||
# CONFIG_SENSORS_PCF8574 is not set
|
||||
# CONFIG_SENSORS_PCF8591 is not set
|
||||
# CONFIG_SENSORS_RTC8564 is not set
|
||||
# CONFIG_SENSORS_M41T00 is not set
|
||||
# CONFIG_I2C_DEBUG_CORE is not set
|
||||
# CONFIG_I2C_DEBUG_ALGO is not set
|
||||
# CONFIG_I2C_DEBUG_BUS is not set
|
||||
|
@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y
|
|||
# Graphics support
|
||||
#
|
||||
# CONFIG_FB is not set
|
||||
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
|
||||
|
||||
#
|
||||
# Sound
|
||||
|
@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y
|
|||
#
|
||||
# USB support
|
||||
#
|
||||
# CONFIG_USB is not set
|
||||
CONFIG_USB_ARCH_HAS_HCD=y
|
||||
CONFIG_USB_ARCH_HAS_OHCI=y
|
||||
|
||||
#
|
||||
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
|
||||
#
|
||||
# CONFIG_USB is not set
|
||||
|
||||
#
|
||||
# USB Gadget Support
|
||||
|
@ -585,6 +647,10 @@ CONFIG_JBD=y
|
|||
CONFIG_FS_MBCACHE=y
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
|
||||
#
|
||||
# XFS support
|
||||
#
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_ROMFS_FS is not set
|
||||
|
@ -646,7 +712,6 @@ CONFIG_NFS_FS=y
|
|||
# CONFIG_NFSD is not set
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_LOCKD=y
|
||||
# CONFIG_EXPORTFS is not set
|
||||
CONFIG_SUNRPC=y
|
||||
# CONFIG_RPCSEC_GSS_KRB5 is not set
|
||||
# CONFIG_RPCSEC_GSS_SPKM3 is not set
|
||||
|
@ -698,7 +763,9 @@ CONFIG_CRC32=y
|
|||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
# CONFIG_PRINTK_TIME is not set
|
||||
# CONFIG_DEBUG_KERNEL is not set
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
# CONFIG_KGDB_CONSOLE is not set
|
||||
# CONFIG_SERIAL_TEXT_DEBUG is not set
|
||||
|
||||
|
|
|
@ -330,8 +330,9 @@ interrupt_base:
|
|||
/* If we are faulting a kernel address, we have to use the
|
||||
* kernel page tables.
|
||||
*/
|
||||
andis. r11, r10, 0x8000
|
||||
beq 3f
|
||||
lis r11, TASK_SIZE@h
|
||||
cmplw r10, r11
|
||||
blt+ 3f
|
||||
lis r11, swapper_pg_dir@h
|
||||
ori r11, r11, swapper_pg_dir@l
|
||||
|
||||
|
@ -464,8 +465,9 @@ interrupt_base:
|
|||
/* If we are faulting a kernel address, we have to use the
|
||||
* kernel page tables.
|
||||
*/
|
||||
andis. r11, r10, 0x8000
|
||||
beq 3f
|
||||
lis r11, TASK_SIZE@h
|
||||
cmplw r10, r11
|
||||
blt+ 3f
|
||||
lis r11, swapper_pg_dir@h
|
||||
ori r11, r11, swapper_pg_dir@l
|
||||
|
||||
|
@ -533,8 +535,9 @@ interrupt_base:
|
|||
/* If we are faulting a kernel address, we have to use the
|
||||
* kernel page tables.
|
||||
*/
|
||||
andis. r11, r10, 0x8000
|
||||
beq 3f
|
||||
lis r11, TASK_SIZE@h
|
||||
cmplw r10, r11
|
||||
blt+ 3f
|
||||
lis r11, swapper_pg_dir@h
|
||||
ori r11, r11, swapper_pg_dir@l
|
||||
|
||||
|
|
|
@ -232,7 +232,8 @@ skpinv: addi r6,r6,1 /* Increment */
|
|||
tlbwe
|
||||
|
||||
/* 7. Jump to KERNELBASE mapping */
|
||||
li r7,0
|
||||
lis r7,MSR_KERNEL@h
|
||||
ori r7,r7,MSR_KERNEL@l
|
||||
bl 1f /* Find our address */
|
||||
1: mflr r9
|
||||
rlwimi r6,r9,0,20,31
|
||||
|
@ -293,6 +294,18 @@ skpinv: addi r6,r6,1 /* Increment */
|
|||
mtspr SPRN_HID0, r2
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_BDI_SWITCH)
|
||||
/*
|
||||
* The Abatron BDI JTAG debugger does not tolerate others
|
||||
* mucking with the debug registers.
|
||||
*/
|
||||
lis r2,DBCR0_IDM@h
|
||||
mtspr SPRN_DBCR0,r2
|
||||
/* clear any residual debug events */
|
||||
li r2,-1
|
||||
mtspr SPRN_DBSR,r2
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is where the main kernel code starts.
|
||||
*/
|
||||
|
|
|
@ -499,7 +499,7 @@ static int __init set_preferred_console(void)
|
|||
{
|
||||
struct device_node *prom_stdout;
|
||||
char *name;
|
||||
int offset;
|
||||
int offset = 0;
|
||||
|
||||
if (of_stdout_device == NULL)
|
||||
return -ENODEV;
|
||||
|
|
|
@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
|
|||
|
||||
/* Early out if we are an invalid form of lswx */
|
||||
if ((instword & INST_STRING_MASK) == INST_LSWX)
|
||||
if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB))
|
||||
return -EINVAL;
|
||||
|
||||
/* Early out if we are an invalid form of lswi */
|
||||
if ((instword & INST_STRING_MASK) == INST_LSWI)
|
||||
if ((rA >= rT) || (rT == rA))
|
||||
if ((rT == rA) || (rT == NB_RB))
|
||||
return -EINVAL;
|
||||
|
||||
EA = (rA == 0) ? 0 : regs->gpr[rA];
|
||||
|
|
|
@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user)
|
|||
#ifdef CONFIG_8xx
|
||||
/* Don't use prefetch on 8xx */
|
||||
mtctr r0
|
||||
li r0,0
|
||||
53: COPY_16_BYTES_WITHEX(0)
|
||||
bdnz 53b
|
||||
|
||||
|
@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user)
|
|||
/* or write fault in cacheline loop */
|
||||
105: li r9,1
|
||||
92: li r3,LG_CACHELINE_BYTES
|
||||
b 99f
|
||||
mfctr r8
|
||||
add r0,r0,r8
|
||||
b 106f
|
||||
/* read fault in final word loop */
|
||||
108: li r9,0
|
||||
b 93f
|
||||
|
@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user)
|
|||
* r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
|
||||
*/
|
||||
99: mfctr r0
|
||||
slw r3,r0,r3
|
||||
106: slw r3,r0,r3
|
||||
add. r3,r3,r5
|
||||
beq 120f /* shouldn't happen */
|
||||
cmpwi 0,r9,0
|
||||
|
|
|
@ -179,6 +179,7 @@ void free_initmem(void)
|
|||
if (!have_of)
|
||||
FREESEC(openfirmware);
|
||||
printk("\n");
|
||||
ppc_md.progress = NULL;
|
||||
#undef FREESEC
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,6 @@ mpc834x_sys_map_io(void)
|
|||
{
|
||||
/* we steal the lowest ioremap addr for virt space */
|
||||
io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
|
||||
io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -26,9 +26,14 @@
|
|||
#define VIRT_IMMRBAR ((uint)0xfe000000)
|
||||
|
||||
#define BCSR_PHYS_ADDR ((uint)0xf8000000)
|
||||
#define BCSR_VIRT_ADDR ((uint)0xfe100000)
|
||||
#define BCSR_SIZE ((uint)(32 * 1024))
|
||||
|
||||
#define BCSR_MISC_REG2_OFF 0x07
|
||||
#define BCSR_MISC_REG2_PORESET 0x01
|
||||
|
||||
#define BCSR_MISC_REG3_OFF 0x08
|
||||
#define BCSR_MISC_REG3_CNFLOCK 0x80
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* PCI interrupt controller */
|
||||
#define PIRQA MPC83xx_IRQ_IRQ4
|
||||
|
|
|
@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
|||
#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
|
||||
ppc_md.progress = gen550_progress;
|
||||
#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
|
||||
#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
|
||||
ppc_md.early_serial_map = mpc85xx_early_serial_map;
|
||||
#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc8540ads_init(): exit", 0);
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <asm/machdep.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/open_pic.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/mpc85xx.h>
|
||||
|
@ -181,6 +182,7 @@ void __init
|
|||
mpc85xx_cds_init_IRQ(void)
|
||||
{
|
||||
bd_t *binfo = (bd_t *) __res;
|
||||
int i;
|
||||
|
||||
/* Determine the Physical Address of the OpenPIC regs */
|
||||
phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
|
||||
|
@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void)
|
|||
*/
|
||||
openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
|
||||
|
||||
for (i = 0; i < NUM_8259_INTERRUPTS; i++)
|
||||
irq_desc[i].handler = &i8259_pic;
|
||||
|
||||
i8259_init(0);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
/* Setup CPM2 PIC */
|
||||
cpm2_init_IRQ();
|
||||
|
@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
|
|||
* interrupt on slot */
|
||||
{
|
||||
{ 0, 1, 2, 3 }, /* 16 - PMC */
|
||||
{ 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */
|
||||
{ 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
|
||||
{ 0, 1, 2, 3 }, /* 18 - Slot 1 */
|
||||
{ 1, 2, 3, 0 }, /* 19 - Slot 2 */
|
||||
{ 2, 3, 0, 1 }, /* 20 - Slot 3 */
|
||||
|
@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
|
|||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
#endif
|
||||
/* We explicitly do not go past the Tundra 320 Bridge */
|
||||
if (bus == 1)
|
||||
if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
else
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
void __init
|
||||
mpc85xx_cds_enable_via(struct pci_controller *hose)
|
||||
{
|
||||
u32 pci_class;
|
||||
u16 vid, did;
|
||||
|
||||
early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
|
||||
if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
|
||||
return;
|
||||
|
||||
/* Configure P2P so that we can reach bus 1 */
|
||||
early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0);
|
||||
early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1);
|
||||
early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff);
|
||||
|
||||
early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
|
||||
early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
|
||||
|
||||
if ((vid != PCI_VENDOR_ID_VIA) ||
|
||||
(did != PCI_DEVICE_ID_VIA_82C686))
|
||||
return;
|
||||
|
||||
/* Enable USB and IDE functions */
|
||||
early_write_config_byte(hose, 1, 0x10, 0x48, 0x08);
|
||||
}
|
||||
|
||||
void __init
|
||||
mpc85xx_cds_fixup_via(struct pci_controller *hose)
|
||||
{
|
||||
u32 pci_class;
|
||||
u16 vid, did;
|
||||
|
||||
early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
|
||||
if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Force the backplane P2P bridge to have a window
|
||||
* open from 0x00000000-0x00001fff in PCI I/O space.
|
||||
* This allows legacy I/O (i8259, etc) on the VIA
|
||||
* southbridge to be accessed.
|
||||
*/
|
||||
early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00);
|
||||
early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000);
|
||||
early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10);
|
||||
early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000);
|
||||
|
||||
early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
|
||||
early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
|
||||
if ((vid != PCI_VENDOR_ID_VIA) ||
|
||||
(did != PCI_DEVICE_ID_VIA_82C686))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Since the P2P window was forced to cover the fixed
|
||||
* legacy I/O addresses, it is necessary to manually
|
||||
* place the base addresses for the IDE and USB functions
|
||||
* within this window.
|
||||
*/
|
||||
/* Function 1, IDE */
|
||||
early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8);
|
||||
early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4);
|
||||
early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8);
|
||||
early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4);
|
||||
early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0);
|
||||
|
||||
/* Function 2, USB ports 0-1 */
|
||||
early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0);
|
||||
|
||||
/* Function 3, USB ports 2-3 */
|
||||
early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80);
|
||||
|
||||
/* Function 5, Power Management */
|
||||
early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00);
|
||||
early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc);
|
||||
early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8);
|
||||
|
||||
/* Function 6, AC97 Interface */
|
||||
early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00);
|
||||
}
|
||||
|
||||
void __init
|
||||
mpc85xx_cds_pcibios_fixup(void)
|
||||
{
|
||||
struct pci_dev *dev = NULL;
|
||||
u_char c;
|
||||
|
||||
if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
|
||||
PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
|
||||
/*
|
||||
* U-Boot does not set the enable bits
|
||||
* for the IDE device. Force them on here.
|
||||
*/
|
||||
pci_read_config_byte(dev, 0x40, &c);
|
||||
c |= 0x03; /* IDE: Chip Enable Bits */
|
||||
pci_write_config_byte(dev, 0x40, c);
|
||||
|
||||
/*
|
||||
* Since only primary interface works, force the
|
||||
* IDE function to standard primary IDE interrupt
|
||||
* w/ 8259 offset
|
||||
*/
|
||||
dev->irq = 14;
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Force legacy USB interrupt routing
|
||||
*/
|
||||
if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
|
||||
PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
|
||||
dev->irq = 10;
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
|
||||
}
|
||||
|
||||
if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
|
||||
PCI_DEVICE_ID_VIA_82C586_2, dev))) {
|
||||
dev->irq = 11;
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
TODC_ALLOC();
|
||||
|
@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void)
|
|||
loops_per_jiffy = freq / HZ;
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* VIA IDE configuration */
|
||||
ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
|
||||
|
||||
/* setup PCI host bridges */
|
||||
mpc85xx_setup_hose();
|
||||
#endif
|
||||
|
@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
|||
#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
|
||||
ppc_md.progress = gen550_progress;
|
||||
#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
|
||||
#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
|
||||
ppc_md.early_serial_map = mpc85xx_early_serial_map;
|
||||
#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("mpc85xx_cds_init(): exit", 0);
|
||||
|
|
|
@ -77,4 +77,7 @@
|
|||
|
||||
#define MPC85XX_PCI2_IO_SIZE 0x01000000
|
||||
|
||||
#define NR_8259_INTS 16
|
||||
#define CPM_IRQ_OFFSET NR_8259_INTS
|
||||
|
||||
#endif /* __MACH_MPC85XX_CDS_H__ */
|
||||
|
|
|
@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
|||
#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
|
||||
ppc_md.progress = gen550_progress;
|
||||
#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
|
||||
#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
|
||||
ppc_md.early_serial_map = sbc8560_early_serial_map;
|
||||
#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */
|
||||
|
||||
if (ppc_md.progress)
|
||||
ppc_md.progress("sbc8560_init(): exit", 0);
|
||||
|
|
|
@ -85,14 +85,11 @@ static int no_schedule;
|
|||
static int has_cpu_l2lve;
|
||||
|
||||
|
||||
#define PMAC_CPU_LOW_SPEED 1
|
||||
#define PMAC_CPU_HIGH_SPEED 0
|
||||
|
||||
/* There are only two frequency states for each processor. Values
|
||||
* are in kHz for the time being.
|
||||
*/
|
||||
#define CPUFREQ_HIGH PMAC_CPU_HIGH_SPEED
|
||||
#define CPUFREQ_LOW PMAC_CPU_LOW_SPEED
|
||||
#define CPUFREQ_HIGH 0
|
||||
#define CPUFREQ_LOW 1
|
||||
|
||||
static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
|
||||
{CPUFREQ_HIGH, 0},
|
||||
|
@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
|
|||
{0, CPUFREQ_TABLE_END},
|
||||
};
|
||||
|
||||
static struct freq_attr* pmac_cpu_freqs_attr[] = {
|
||||
&cpufreq_freq_attr_scaling_available_freqs,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static inline void local_delay(unsigned long ms)
|
||||
{
|
||||
if (no_schedule)
|
||||
|
@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
|
|||
#ifdef DEBUG_FREQ
|
||||
printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
|
||||
#endif
|
||||
pmu_suspend();
|
||||
|
||||
/* Disable all interrupt sources on openpic */
|
||||
pic_prio = openpic_get_priority();
|
||||
openpic_set_priority(0xf);
|
||||
|
@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
|
|||
debug_calc_bogomips();
|
||||
#endif
|
||||
|
||||
pmu_resume();
|
||||
|
||||
preempt_enable();
|
||||
|
||||
return 0;
|
||||
|
@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
|
|||
static unsigned long prev_l3cr;
|
||||
|
||||
freqs.old = cur_freq;
|
||||
freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
|
||||
freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
|
||||
freqs.cpu = smp_processor_id();
|
||||
|
||||
if (freqs.old == freqs.new)
|
||||
|
@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
|
|||
|
||||
if (notify)
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
if (speed_mode == PMAC_CPU_LOW_SPEED &&
|
||||
if (speed_mode == CPUFREQ_LOW &&
|
||||
cpu_has_feature(CPU_FTR_L3CR)) {
|
||||
l3cr = _get_L3CR();
|
||||
if (l3cr & L3CR_L3E) {
|
||||
|
@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
|
|||
_set_L3CR(0);
|
||||
}
|
||||
}
|
||||
set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED);
|
||||
if (speed_mode == PMAC_CPU_HIGH_SPEED &&
|
||||
set_speed_proc(speed_mode == CPUFREQ_LOW);
|
||||
if (speed_mode == CPUFREQ_HIGH &&
|
||||
cpu_has_feature(CPU_FTR_L3CR)) {
|
||||
l3cr = _get_L3CR();
|
||||
if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
|
||||
|
@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
|
|||
}
|
||||
if (notify)
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
|
||||
cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
|||
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
|
||||
policy->cur = cur_freq;
|
||||
|
||||
return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]);
|
||||
cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
|
||||
return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
|
||||
}
|
||||
|
||||
static u32 __pmac read_gpio(struct device_node *np)
|
||||
|
@ -457,7 +464,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
|
|||
no_schedule = 1;
|
||||
sleep_freq = cur_freq;
|
||||
if (cur_freq == low_freq)
|
||||
do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0);
|
||||
do_set_cpu_speed(CPUFREQ_HIGH, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
|
|||
* is that we force a switch to whatever it was, which is
|
||||
* probably high speed due to our suspend() routine
|
||||
*/
|
||||
do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED
|
||||
: PMAC_CPU_HIGH_SPEED, 0);
|
||||
do_set_cpu_speed(sleep_freq == low_freq ?
|
||||
CPUFREQ_LOW : CPUFREQ_HIGH, 0);
|
||||
|
||||
no_schedule = 0;
|
||||
return 0;
|
||||
|
@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
|
|||
.suspend = pmac_cpufreq_suspend,
|
||||
.resume = pmac_cpufreq_resume,
|
||||
.flags = CPUFREQ_PM_NO_WARN,
|
||||
.attr = pmac_cpu_freqs_attr,
|
||||
.name = "powermac",
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
|
|
@ -49,10 +49,10 @@
|
|||
/* PCI interrupt controller */
|
||||
#define PCI_INT_STAT_REG 0xF8200000
|
||||
#define PCI_INT_MASK_REG 0xF8200004
|
||||
#define PIRQA (NR_SIU_INTS + 0)
|
||||
#define PIRQB (NR_SIU_INTS + 1)
|
||||
#define PIRQC (NR_SIU_INTS + 2)
|
||||
#define PIRQD (NR_SIU_INTS + 3)
|
||||
#define PIRQA (NR_CPM_INTS + 0)
|
||||
#define PIRQB (NR_CPM_INTS + 1)
|
||||
#define PIRQC (NR_CPM_INTS + 2)
|
||||
#define PIRQD (NR_CPM_INTS + 3)
|
||||
|
||||
/*
|
||||
* PCI memory map definitions for MPC8266ADS-PCI.
|
||||
|
@ -68,28 +68,23 @@
|
|||
* 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory
|
||||
*/
|
||||
|
||||
/* window for a PCI master to access MPC8266 memory */
|
||||
#define PCI_SLV_MEM_LOCAL 0x00000000 /* Local base */
|
||||
#define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */
|
||||
/* All the other PCI memory map definitions reside at syslib/m82xx_pci.h
|
||||
Here we should redefine what is unique for this board */
|
||||
#define M82xx_PCI_SLAVE_MEM_LOCAL 0x00000000 /* Local base */
|
||||
#define M82xx_PCI_SLAVE_MEM_BUS 0x00000000 /* PCI base */
|
||||
#define M82xx_PCI_SLAVE_MEM_SIZE 0x10000000 /* 256 Mb */
|
||||
|
||||
/* window for the processor to access PCI memory with prefetching */
|
||||
#define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */
|
||||
#define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */
|
||||
#define PCI_MSTR_MEM_SIZE 0x20000000 /* 512MB */
|
||||
#define M82xx_PCI_SLAVE_SEC_WND_SIZE ~(0x40000000 - 1U) /* 2 x 512Mb */
|
||||
#define M82xx_PCI_SLAVE_SEC_WND_BASE 0x80000000 /* PCI Memory base */
|
||||
|
||||
/* window for the processor to access PCI memory without prefetching */
|
||||
#define PCI_MSTR_MEMIO_LOCAL 0xA0000000 /* Local base */
|
||||
#define PCI_MSTR_MEMIO_BUS 0xA0000000 /* PCI base */
|
||||
#define PCI_MSTR_MEMIO_SIZE 0x20000000 /* 512MB */
|
||||
#if defined(CONFIG_ADS8272)
|
||||
#define PCI_INT_TO_SIU SIU_INT_IRQ2
|
||||
#elif defined(CONFIG_PQ2FADS)
|
||||
#define PCI_INT_TO_SIU SIU_INT_IRQ6
|
||||
#else
|
||||
#warning PCI Bridge will be without interrupts support
|
||||
#endif
|
||||
|
||||
/* window for the processor to access PCI I/O */
|
||||
#define PCI_MSTR_IO_LOCAL 0xF4000000 /* Local base */
|
||||
#define PCI_MSTR_IO_BUS 0x00000000 /* PCI base */
|
||||
#define PCI_MSTR_IO_SIZE 0x04000000 /* 64MB */
|
||||
|
||||
#define _IO_BASE PCI_MSTR_IO_LOCAL
|
||||
#define _ISA_MEM_BASE PCI_MSTR_MEMIO_LOCAL
|
||||
#define PCI_DRAM_OFFSET PCI_SLV_MEM_BUS
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#endif /* __MACH_ADS8260_DEFS */
|
||||
|
|
|
@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx) += todc_time.o
|
|||
obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \
|
||||
todc_time.o
|
||||
obj-$(CONFIG_8260) += m8260_setup.o
|
||||
obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o
|
||||
obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o
|
||||
obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o
|
||||
obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
|
||||
ifeq ($(CONFIG_PPC_GEN550),y)
|
||||
|
@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o
|
|||
obj-$(CONFIG_40x) += dcr.o
|
||||
obj-$(CONFIG_BOOKE) += dcr.o
|
||||
obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \
|
||||
ppc_sys.o mpc85xx_sys.o \
|
||||
ppc_sys.o i8259.o mpc85xx_sys.o \
|
||||
mpc85xx_devices.o
|
||||
ifeq ($(CONFIG_85xx),y)
|
||||
obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
|
||||
|
|
|
@ -479,7 +479,7 @@ void __init ipic_init(phys_addr_t phys_addr,
|
|||
temp = 0;
|
||||
for (i = 0 ; i < senses_count ; i++) {
|
||||
if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
|
||||
temp |= 1 << (16 - i);
|
||||
temp |= 1 << (15 - i);
|
||||
if (i != 0)
|
||||
irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
|
||||
else
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2004 Red Hat, Inc.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/immap_cpm2.h>
|
||||
#include <asm/mpc8260.h>
|
||||
|
||||
#include "m8260_pci.h"
|
||||
|
||||
|
||||
/* PCI bus configuration registers.
|
||||
*/
|
||||
|
||||
static void __init m8260_setup_pci(struct pci_controller *hose)
|
||||
{
|
||||
volatile cpm2_map_t *immap = cpm2_immr;
|
||||
unsigned long pocmr;
|
||||
u16 tempShort;
|
||||
|
||||
#ifndef CONFIG_ATC /* already done in U-Boot */
|
||||
/*
|
||||
* Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
|
||||
* and local bus for PCI (SIUMCR [LBPC]).
|
||||
*/
|
||||
immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000;
|
||||
#endif
|
||||
|
||||
/* Make PCI lowest priority */
|
||||
/* Each 4 bits is a device bus request and the MS 4bits
|
||||
is highest priority */
|
||||
/* Bus 4bit value
|
||||
--- ----------
|
||||
CPM high 0b0000
|
||||
CPM middle 0b0001
|
||||
CPM low 0b0010
|
||||
PCI reguest 0b0011
|
||||
Reserved 0b0100
|
||||
Reserved 0b0101
|
||||
Internal Core 0b0110
|
||||
External Master 1 0b0111
|
||||
External Master 2 0b1000
|
||||
External Master 3 0b1001
|
||||
The rest are reserved */
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
|
||||
|
||||
/* Park bus on core while modifying PCI Bus accesses */
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6;
|
||||
|
||||
/*
|
||||
* Set up master window that allows the CPU to access PCI space. This
|
||||
* window is set up using the first SIU PCIBR registers.
|
||||
*/
|
||||
immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK;
|
||||
immap->im_memctl.memc_pcibr0 = MPC826x_PCI_BASE | PCIBR_ENABLE;
|
||||
|
||||
/* Disable machine check on no response or target abort */
|
||||
immap->im_pci.pci_emr = cpu_to_le32(0x1fe7);
|
||||
/* Release PCI RST (by default the PCI RST signal is held low) */
|
||||
immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
|
||||
|
||||
/* give it some time */
|
||||
mdelay(1);
|
||||
|
||||
/*
|
||||
* Set up master window that allows the CPU to access PCI Memory (prefetch)
|
||||
* space. This window is set up using the first set of Outbound ATU registers.
|
||||
*/
|
||||
immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12);
|
||||
immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12);
|
||||
pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff;
|
||||
immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN);
|
||||
|
||||
/*
|
||||
* Set up master window that allows the CPU to access PCI Memory (non-prefetch)
|
||||
* space. This window is set up using the second set of Outbound ATU registers.
|
||||
*/
|
||||
immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12);
|
||||
immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12);
|
||||
pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff;
|
||||
immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE);
|
||||
|
||||
/*
|
||||
* Set up master window that allows the CPU to access PCI IO space. This window
|
||||
* is set up using the third set of Outbound ATU registers.
|
||||
*/
|
||||
immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12);
|
||||
immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12);
|
||||
pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff;
|
||||
immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO);
|
||||
|
||||
/*
|
||||
* Set up slave window that allows PCI masters to access MPC826x local memory.
|
||||
* This window is set up using the first set of Inbound ATU registers
|
||||
*/
|
||||
|
||||
immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12);
|
||||
immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12);
|
||||
pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff;
|
||||
immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN);
|
||||
|
||||
/* See above for description - puts PCI request as highest priority */
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
|
||||
|
||||
/* Park the bus on the PCI */
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
|
||||
|
||||
/* Host mode - specify the bridge as a host-PCI bridge */
|
||||
early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST);
|
||||
|
||||
/* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */
|
||||
early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort);
|
||||
early_write_config_word(hose, 0, 0, PCI_COMMAND,
|
||||
tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
|
||||
}
|
||||
|
||||
void __init m8260_find_bridges(void)
|
||||
{
|
||||
extern int pci_assign_all_busses;
|
||||
struct pci_controller * hose;
|
||||
|
||||
pci_assign_all_busses = 1;
|
||||
|
||||
hose = pcibios_alloc_controller();
|
||||
|
||||
if (!hose)
|
||||
return;
|
||||
|
||||
ppc_md.pci_swizzle = common_swizzle;
|
||||
|
||||
hose->first_busno = 0;
|
||||
hose->bus_offset = 0;
|
||||
hose->last_busno = 0xff;
|
||||
|
||||
setup_m8260_indirect_pci(hose,
|
||||
(unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
|
||||
(unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
|
||||
|
||||
m8260_setup_pci(hose);
|
||||
hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET;
|
||||
|
||||
hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE,
|
||||
MPC826x_PCI_IO_SIZE);
|
||||
isa_io_base = (unsigned long) hose->io_base_virt;
|
||||
|
||||
/* setup resources */
|
||||
pci_init_resource(&hose->mem_resources[0],
|
||||
MPC826x_PCI_LOWER_MEM,
|
||||
MPC826x_PCI_UPPER_MEM,
|
||||
IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
|
||||
|
||||
pci_init_resource(&hose->mem_resources[1],
|
||||
MPC826x_PCI_LOWER_MMIO,
|
||||
MPC826x_PCI_UPPER_MMIO,
|
||||
IORESOURCE_MEM, "PCI memory");
|
||||
|
||||
pci_init_resource(&hose->io_resource,
|
||||
MPC826x_PCI_LOWER_IO,
|
||||
MPC826x_PCI_UPPER_IO,
|
||||
IORESOURCE_IO, "PCI I/O");
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
|
||||
#ifndef _PPC_KERNEL_M8260_PCI_H
|
||||
#define _PPC_KERNEL_M8260_PCI_H
|
||||
|
||||
#include <asm/m8260_pci.h>
|
||||
|
||||
/*
|
||||
* Local->PCI map (from CPU) controlled by
|
||||
* MPC826x master window
|
||||
*
|
||||
* 0x80000000 - 0xBFFFFFFF Total CPU2PCI space PCIBR0
|
||||
*
|
||||
* 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1)
|
||||
* 0xA0000000 - 0xAFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2)
|
||||
* 0xB0000000 - 0xB0FFFFFF 32-bit PCI IO (Outbound ATU #3)
|
||||
*
|
||||
* PCI->Local map (from PCI)
|
||||
* MPC826x slave window controlled by
|
||||
*
|
||||
* 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Slave window that allows PCI masters to access MPC826x local memory.
|
||||
* This window is set up using the first set of Inbound ATU registers
|
||||
*/
|
||||
|
||||
#ifndef MPC826x_PCI_SLAVE_MEM_LOCAL
|
||||
#define MPC826x_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart)
|
||||
#define MPC826x_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart)
|
||||
#define MPC826x_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the window that allows the CPU to access PCI address space.
|
||||
* It will be setup with the SIU PCIBR0 register. All three PCI master
|
||||
* windows, which allow the CPU to access PCI prefetch, non prefetch,
|
||||
* and IO space (see below), must all fit within this window.
|
||||
*/
|
||||
#ifndef MPC826x_PCI_BASE
|
||||
#define MPC826x_PCI_BASE 0x80000000
|
||||
#define MPC826x_PCI_MASK 0xc0000000
|
||||
#endif
|
||||
|
||||
#ifndef MPC826x_PCI_LOWER_MEM
|
||||
#define MPC826x_PCI_LOWER_MEM 0x80000000
|
||||
#define MPC826x_PCI_UPPER_MEM 0x9fffffff
|
||||
#define MPC826x_PCI_MEM_OFFSET 0x00000000
|
||||
#endif
|
||||
|
||||
#ifndef MPC826x_PCI_LOWER_MMIO
|
||||
#define MPC826x_PCI_LOWER_MMIO 0xa0000000
|
||||
#define MPC826x_PCI_UPPER_MMIO 0xafffffff
|
||||
#define MPC826x_PCI_MMIO_OFFSET 0x00000000
|
||||
#endif
|
||||
|
||||
#ifndef MPC826x_PCI_LOWER_IO
|
||||
#define MPC826x_PCI_LOWER_IO 0x00000000
|
||||
#define MPC826x_PCI_UPPER_IO 0x00ffffff
|
||||
#define MPC826x_PCI_IO_BASE 0xb0000000
|
||||
#define MPC826x_PCI_IO_SIZE 0x01000000
|
||||
#endif
|
||||
|
||||
#ifndef _IO_BASE
|
||||
#define _IO_BASE isa_io_base
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_8260_PCI9
|
||||
struct pci_controller;
|
||||
extern void setup_m8260_indirect_pci(struct pci_controller* hose,
|
||||
u32 cfg_addr, u32 cfg_data);
|
||||
#else
|
||||
#define setup_m8260_indirect_pci setup_indirect_pci
|
||||
#endif
|
||||
|
||||
#endif /* _PPC_KERNEL_M8260_PCI_H */
|
|
@ -31,7 +31,7 @@
|
|||
#include <asm/immap_cpm2.h>
|
||||
#include <asm/cpm2.h>
|
||||
|
||||
#include "m8260_pci.h"
|
||||
#include "m82xx_pci.h"
|
||||
|
||||
#ifdef CONFIG_8260_PCI9
|
||||
/*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
|
||||
|
@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le);
|
|||
|
||||
static inline int is_pci_mem(unsigned long addr)
|
||||
{
|
||||
if (addr >= MPC826x_PCI_LOWER_MMIO &&
|
||||
addr <= MPC826x_PCI_UPPER_MMIO)
|
||||
if (addr >= M82xx_PCI_LOWER_MMIO &&
|
||||
addr <= M82xx_PCI_UPPER_MMIO)
|
||||
return 1;
|
||||
if (addr >= MPC826x_PCI_LOWER_MEM &&
|
||||
addr <= MPC826x_PCI_UPPER_MEM)
|
||||
if (addr >= M82xx_PCI_LOWER_MEM &&
|
||||
addr <= M82xx_PCI_UPPER_MEM)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
unsigned char __res[sizeof(bd_t)];
|
||||
|
||||
extern void cpm2_reset(void);
|
||||
extern void m8260_find_bridges(void);
|
||||
extern void pq2_find_bridges(void);
|
||||
extern void pq2pci_init_irq(void);
|
||||
extern void idma_pci9_init(void);
|
||||
|
||||
/* Place-holder for board-specific init */
|
||||
|
@ -56,7 +57,7 @@ m8260_setup_arch(void)
|
|||
idma_pci9_init();
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_8260
|
||||
m8260_find_bridges();
|
||||
pq2_find_bridges();
|
||||
#endif
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
if (initrd_start)
|
||||
|
@ -173,6 +174,12 @@ m8260_init_IRQ(void)
|
|||
* in case the boot rom changed something on us.
|
||||
*/
|
||||
cpm2_immr->im_intctl.ic_siprr = 0x05309770;
|
||||
|
||||
#if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS))
|
||||
/* Initialize stuff for the 82xx CPLD IC and install demux */
|
||||
pq2pci_init_irq();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2004 Red Hat, Inc.
|
||||
*
|
||||
* 2005 (c) MontaVista Software, Inc.
|
||||
* Vitaly Bordug <vbordug@ru.mvista.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/immap_cpm2.h>
|
||||
#include <asm/mpc8260.h>
|
||||
#include <asm/cpm2.h>
|
||||
|
||||
#include "m82xx_pci.h"
|
||||
|
||||
/*
|
||||
* Interrupt routing
|
||||
*/
|
||||
|
||||
static inline int
|
||||
pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
|
||||
{
|
||||
static char pci_irq_table[][4] =
|
||||
/*
|
||||
* PCI IDSEL/INTPIN->INTLINE
|
||||
* A B C D
|
||||
*/
|
||||
{
|
||||
{ PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */
|
||||
{ PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */
|
||||
{ PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */
|
||||
};
|
||||
|
||||
const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4;
|
||||
return PCI_IRQ_TABLE_LOOKUP;
|
||||
}
|
||||
|
||||
static void
|
||||
pq2pci_mask_irq(unsigned int irq)
|
||||
{
|
||||
int bit = irq - NR_CPM_INTS;
|
||||
|
||||
*(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
pq2pci_unmask_irq(unsigned int irq)
|
||||
{
|
||||
int bit = irq - NR_CPM_INTS;
|
||||
|
||||
*(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
pq2pci_mask_and_ack(unsigned int irq)
|
||||
{
|
||||
int bit = irq - NR_CPM_INTS;
|
||||
|
||||
*(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
pq2pci_end_irq(unsigned int irq)
|
||||
{
|
||||
int bit = irq - NR_CPM_INTS;
|
||||
|
||||
*(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
|
||||
return;
|
||||
}
|
||||
|
||||
struct hw_interrupt_type pq2pci_ic = {
|
||||
"PQ2 PCI",
|
||||
NULL,
|
||||
NULL,
|
||||
pq2pci_unmask_irq,
|
||||
pq2pci_mask_irq,
|
||||
pq2pci_mask_and_ack,
|
||||
pq2pci_end_irq,
|
||||
0
|
||||
};
|
||||
|
||||
static irqreturn_t
|
||||
pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long stat, mask, pend;
|
||||
int bit;
|
||||
|
||||
for(;;) {
|
||||
stat = *(volatile unsigned long *) PCI_INT_STAT_REG;
|
||||
mask = *(volatile unsigned long *) PCI_INT_MASK_REG;
|
||||
pend = stat & ~mask & 0xf0000000;
|
||||
if (!pend)
|
||||
break;
|
||||
for (bit = 0; pend != 0; ++bit, pend <<= 1) {
|
||||
if (pend & 0x80000000)
|
||||
__do_IRQ(NR_CPM_INTS + bit, regs);
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction pq2pci_irqaction = {
|
||||
.handler = pq2pci_irq_demux,
|
||||
.flags = SA_INTERRUPT,
|
||||
.mask = CPU_MASK_NONE,
|
||||
.name = "PQ2 PCI cascade",
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
pq2pci_init_irq(void)
|
||||
{
|
||||
int irq;
|
||||
volatile cpm2_map_t *immap = cpm2_immr;
|
||||
#if defined CONFIG_ADS8272
|
||||
/* configure chip select for PCI interrupt controller */
|
||||
immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801;
|
||||
immap->im_memctl.memc_or3 = 0xffff8010;
|
||||
#elif defined CONFIG_PQ2FADS
|
||||
immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801;
|
||||
immap->im_memctl.memc_or8 = 0xffff8010;
|
||||
#endif
|
||||
for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++)
|
||||
irq_desc[irq].handler = &pq2pci_ic;
|
||||
|
||||
/* make PCI IRQ level sensitive */
|
||||
immap->im_intctl.ic_siexr &=
|
||||
~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1)));
|
||||
|
||||
/* mask all PCI interrupts */
|
||||
*(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000;
|
||||
|
||||
/* install the demultiplexer for the PCI cascade interrupt */
|
||||
setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
pq2pci_exclude_device(u_char bus, u_char devfn)
|
||||
{
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/* PCI bus configuration registers.
|
||||
*/
|
||||
static void
|
||||
pq2ads_setup_pci(struct pci_controller *hose)
|
||||
{
|
||||
__u32 val;
|
||||
volatile cpm2_map_t *immap = cpm2_immr;
|
||||
bd_t* binfo = (bd_t*) __res;
|
||||
u32 sccr = immap->im_clkrst.car_sccr;
|
||||
uint pci_div,freq,time;
|
||||
/* PCI int lowest prio */
|
||||
/* Each 4 bits is a device bus request and the MS 4bits
|
||||
is highest priority */
|
||||
/* Bus 4bit value
|
||||
--- ----------
|
||||
CPM high 0b0000
|
||||
CPM middle 0b0001
|
||||
CPM low 0b0010
|
||||
PCI reguest 0b0011
|
||||
Reserved 0b0100
|
||||
Reserved 0b0101
|
||||
Internal Core 0b0110
|
||||
External Master 1 0b0111
|
||||
External Master 2 0b1000
|
||||
External Master 3 0b1001
|
||||
The rest are reserved
|
||||
*/
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
|
||||
/* park bus on core */
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE;
|
||||
/*
|
||||
* Set up master windows that allow the CPU to access PCI space. These
|
||||
* windows are set up using the two SIU PCIBR registers.
|
||||
*/
|
||||
|
||||
immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE;
|
||||
immap->im_memctl.memc_pcibr0 = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE;
|
||||
|
||||
#ifdef M82xx_PCI_SEC_WND_SIZE
|
||||
immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE;
|
||||
immap->im_memctl.memc_pcibr1 = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE;
|
||||
#endif
|
||||
|
||||
#if defined CONFIG_ADS8272
|
||||
immap->im_siu_conf.siu_82xx.sc_siumcr =
|
||||
(immap->im_siu_conf.siu_82xx.sc_siumcr &
|
||||
~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE |
|
||||
SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 |
|
||||
SIUMCR_LBPC11 | SIUMCR_APPC11 |
|
||||
SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) |
|
||||
SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 |
|
||||
SIUMCR_APPC10 | SIUMCR_CS10PC00 |
|
||||
SIUMCR_BCTLC00 | SIUMCR_MMR11 ;
|
||||
|
||||
#elif defined CONFIG_PQ2FADS
|
||||
/*
|
||||
* Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
|
||||
* and local bus for PCI (SIUMCR [LBPC]).
|
||||
*/
|
||||
immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
|
||||
~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
|
||||
SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10;
|
||||
#endif
|
||||
/* Enable PCI */
|
||||
immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
|
||||
|
||||
pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
|
||||
( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
|
||||
freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
|
||||
time = (int)666666/freq;
|
||||
/* due to PCI Local Bus spec, some devices needs to wait such a long
|
||||
time after RST deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
|
||||
printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
|
||||
(time==1) ? "0.5 seconds":"1 second" );
|
||||
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<(500*time);i++)
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
/* setup ATU registers */
|
||||
immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO |
|
||||
((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT));
|
||||
immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT);
|
||||
immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT);
|
||||
|
||||
/* Set-up non-prefetchable window */
|
||||
immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT));
|
||||
immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT);
|
||||
immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT);
|
||||
|
||||
/* Set-up prefetchable window */
|
||||
immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN |
|
||||
(~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT));
|
||||
immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT);
|
||||
immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT);
|
||||
|
||||
/* Inbound transactions from PCI memory space */
|
||||
immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN |
|
||||
((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT));
|
||||
immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS >> PITA_ADDR_SHIFT);
|
||||
immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT);
|
||||
|
||||
#if defined CONFIG_ADS8272
|
||||
/* PCI int highest prio */
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745;
|
||||
#elif defined CONFIG_PQ2FADS
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
|
||||
#endif
|
||||
/* park bus on PCI */
|
||||
immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
|
||||
|
||||
/* Enable bus mastering and inbound memory transactions */
|
||||
early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val);
|
||||
val &= 0xffff0000;
|
||||
val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER;
|
||||
early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val);
|
||||
|
||||
}
|
||||
|
||||
void __init pq2_find_bridges(void)
|
||||
{
|
||||
extern int pci_assign_all_busses;
|
||||
struct pci_controller * hose;
|
||||
int host_bridge;
|
||||
|
||||
pci_assign_all_busses = 1;
|
||||
|
||||
hose = pcibios_alloc_controller();
|
||||
|
||||
if (!hose)
|
||||
return;
|
||||
|
||||
ppc_md.pci_swizzle = common_swizzle;
|
||||
|
||||
hose->first_busno = 0;
|
||||
hose->bus_offset = 0;
|
||||
hose->last_busno = 0xff;
|
||||
|
||||
#ifdef CONFIG_ADS8272
|
||||
hose->set_cfg_type = 1;
|
||||
#endif
|
||||
|
||||
setup_m8260_indirect_pci(hose,
|
||||
(unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
|
||||
(unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
|
||||
|
||||
/* Make sure it is a supported bridge */
|
||||
early_read_config_dword(hose,
|
||||
0,
|
||||
PCI_DEVFN(0,0),
|
||||
PCI_VENDOR_ID,
|
||||
&host_bridge);
|
||||
switch (host_bridge) {
|
||||
case PCI_DEVICE_ID_MPC8265:
|
||||
break;
|
||||
case PCI_DEVICE_ID_MPC8272:
|
||||
break;
|
||||
default:
|
||||
printk("Attempting to use unrecognized host bridge ID"
|
||||
" 0x%08x.\n", host_bridge);
|
||||
break;
|
||||
}
|
||||
|
||||
pq2ads_setup_pci(hose);
|
||||
|
||||
hose->io_space.start = M82xx_PCI_LOWER_IO;
|
||||
hose->io_space.end = M82xx_PCI_UPPER_IO;
|
||||
hose->mem_space.start = M82xx_PCI_LOWER_MEM;
|
||||
hose->mem_space.end = M82xx_PCI_UPPER_MMIO;
|
||||
hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET;
|
||||
|
||||
isa_io_base =
|
||||
(unsigned long) ioremap(M82xx_PCI_IO_BASE,
|
||||
M82xx_PCI_IO_SIZE);
|
||||
hose->io_base_virt = (void *) isa_io_base;
|
||||
|
||||
/* setup resources */
|
||||
pci_init_resource(&hose->mem_resources[0],
|
||||
M82xx_PCI_LOWER_MEM,
|
||||
M82xx_PCI_UPPER_MEM,
|
||||
IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
|
||||
|
||||
pci_init_resource(&hose->mem_resources[1],
|
||||
M82xx_PCI_LOWER_MMIO,
|
||||
M82xx_PCI_UPPER_MMIO,
|
||||
IORESOURCE_MEM, "PCI memory");
|
||||
|
||||
pci_init_resource(&hose->io_resource,
|
||||
M82xx_PCI_LOWER_IO,
|
||||
M82xx_PCI_UPPER_IO,
|
||||
IORESOURCE_IO | 1, "PCI I/O");
|
||||
|
||||
ppc_md.pci_exclude_device = pq2pci_exclude_device;
|
||||
hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
|
||||
|
||||
ppc_md.pci_map_irq = pq2pci_map_irq;
|
||||
ppc_md.pcibios_fixup = NULL;
|
||||
ppc_md.pcibios_fixup_bus = NULL;
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
#ifndef _PPC_KERNEL_M82XX_PCI_H
|
||||
#define _PPC_KERNEL_M82XX_PCI_H
|
||||
|
||||
#include <asm/m8260_pci.h>
|
||||
/*
|
||||
* Local->PCI map (from CPU) controlled by
|
||||
* MPC826x master window
|
||||
*
|
||||
* 0xF6000000 - 0xF7FFFFFF IO space
|
||||
* 0x80000000 - 0xBFFFFFFF CPU2PCI memory space PCIBR0
|
||||
*
|
||||
* 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1)
|
||||
* 0xA0000000 - 0xBFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2)
|
||||
* 0xF6000000 - 0xF7FFFFFF 32-bit PCI IO (Outbound ATU #3)
|
||||
*
|
||||
* PCI->Local map (from PCI)
|
||||
* MPC826x slave window controlled by
|
||||
*
|
||||
* 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Slave window that allows PCI masters to access MPC826x local memory.
|
||||
* This window is set up using the first set of Inbound ATU registers
|
||||
*/
|
||||
|
||||
#ifndef M82xx_PCI_SLAVE_MEM_LOCAL
|
||||
#define M82xx_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart)
|
||||
#define M82xx_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart)
|
||||
#define M82xx_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the window that allows the CPU to access PCI address space.
|
||||
* It will be setup with the SIU PCIBR0 register. All three PCI master
|
||||
* windows, which allow the CPU to access PCI prefetch, non prefetch,
|
||||
* and IO space (see below), must all fit within this window.
|
||||
*/
|
||||
|
||||
#ifndef M82xx_PCI_LOWER_MEM
|
||||
#define M82xx_PCI_LOWER_MEM 0x80000000
|
||||
#define M82xx_PCI_UPPER_MEM 0x9fffffff
|
||||
#define M82xx_PCI_MEM_OFFSET 0x00000000
|
||||
#define M82xx_PCI_MEM_SIZE 0x20000000
|
||||
#endif
|
||||
|
||||
#ifndef M82xx_PCI_LOWER_MMIO
|
||||
#define M82xx_PCI_LOWER_MMIO 0xa0000000
|
||||
#define M82xx_PCI_UPPER_MMIO 0xafffffff
|
||||
#define M82xx_PCI_MMIO_OFFSET 0x00000000
|
||||
#define M82xx_PCI_MMIO_SIZE 0x20000000
|
||||
#endif
|
||||
|
||||
#ifndef M82xx_PCI_LOWER_IO
|
||||
#define M82xx_PCI_LOWER_IO 0x00000000
|
||||
#define M82xx_PCI_UPPER_IO 0x01ffffff
|
||||
#define M82xx_PCI_IO_BASE 0xf6000000
|
||||
#define M82xx_PCI_IO_SIZE 0x02000000
|
||||
#endif
|
||||
|
||||
#ifndef M82xx_PCI_PRIM_WND_SIZE
|
||||
#define M82xx_PCI_PRIM_WND_SIZE ~(M82xx_PCI_IO_SIZE - 1U)
|
||||
#define M82xx_PCI_PRIM_WND_BASE (M82xx_PCI_IO_BASE)
|
||||
#endif
|
||||
|
||||
#ifndef M82xx_PCI_SEC_WND_SIZE
|
||||
#define M82xx_PCI_SEC_WND_SIZE ~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U)
|
||||
#define M82xx_PCI_SEC_WND_BASE (M82xx_PCI_LOWER_MEM)
|
||||
#endif
|
||||
|
||||
#ifndef POTA_ADDR_SHIFT
|
||||
#define POTA_ADDR_SHIFT 12
|
||||
#endif
|
||||
|
||||
#ifndef PITA_ADDR_SHIFT
|
||||
#define PITA_ADDR_SHIFT 12
|
||||
#endif
|
||||
|
||||
#ifndef _IO_BASE
|
||||
#define _IO_BASE isa_io_base
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_8260_PCI9
|
||||
struct pci_controller;
|
||||
extern void setup_m8260_indirect_pci(struct pci_controller* hose,
|
||||
u32 cfg_addr, u32 cfg_data);
|
||||
#else
|
||||
#define setup_m8260_indirect_pci setup_indirect_pci
|
||||
#endif
|
||||
|
||||
#endif /* _PPC_KERNEL_M8260_PCI_H */
|
|
@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
|
|||
.iotype = UPIO_MEM,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
struct platform_device ppc_sys_platform_devices[] = {
|
||||
|
|
|
@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
|
|||
.iotype = UPIO_MEM,
|
||||
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
struct platform_device ppc_sys_platform_devices[] = {
|
||||
|
|
|
@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM)
|
||||
#if defined(CONFIG_EPIC_SERIAL_MODE)
|
||||
static void openpic_reset(void)
|
||||
{
|
||||
openpic_setfield(&OpenPIC->Global.Global_Configuration0,
|
||||
|
@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
|
|||
*/
|
||||
void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
|
||||
{
|
||||
cpumask_t phys;
|
||||
DECL_THIS_CPU;
|
||||
|
||||
CHECK_THIS_CPU;
|
||||
check_arg_ipi(ipi);
|
||||
phys = physmask(cpumask);
|
||||
openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
|
||||
cpus_addr(physmask(cpumask))[0]);
|
||||
}
|
||||
|
@ -995,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
openpic_reset();
|
||||
|
||||
/* OpenPIC sometimes seem to need some time to be fully back up... */
|
||||
do {
|
||||
openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <asm/mmu.h>
|
||||
#include <asm/ppc_sys.h>
|
||||
#include <asm/kgdb.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
#include <syslib/ppc83xx_setup.h>
|
||||
|
||||
|
@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void)
|
|||
void
|
||||
mpc83xx_restart(char *cmd)
|
||||
{
|
||||
volatile unsigned char __iomem *reg;
|
||||
unsigned char tmp;
|
||||
|
||||
reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
/*
|
||||
* Unlock the BCSR bits so a PRST will update the contents.
|
||||
* Otherwise the reset asserts but doesn't clear.
|
||||
*/
|
||||
tmp = in_8(reg + BCSR_MISC_REG3_OFF);
|
||||
tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
|
||||
out_8(reg + BCSR_MISC_REG3_OFF, tmp);
|
||||
|
||||
/*
|
||||
* Trigger a reset via a low->high transition of the
|
||||
* PORESET bit.
|
||||
*/
|
||||
tmp = in_8(reg + BCSR_MISC_REG2_OFF);
|
||||
tmp &= ~BCSR_MISC_REG2_PORESET;
|
||||
out_8(reg + BCSR_MISC_REG2_OFF, tmp);
|
||||
|
||||
udelay(1);
|
||||
|
||||
tmp |= BCSR_MISC_REG2_PORESET;
|
||||
out_8(reg + BCSR_MISC_REG2_OFF, tmp);
|
||||
|
||||
for(;;);
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,12 @@ mpc85xx_halt(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
#if defined(CONFIG_MPC8555_CDS)
|
||||
extern void mpc85xx_cds_enable_via(struct pci_controller *hose);
|
||||
extern void mpc85xx_cds_fixup_via(struct pci_controller *hose);
|
||||
#endif
|
||||
|
||||
static void __init
|
||||
mpc85xx_setup_pci1(struct pci_controller *hose)
|
||||
{
|
||||
|
@ -302,8 +308,18 @@ mpc85xx_setup_hose(void)
|
|||
|
||||
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
|
||||
|
||||
#if defined(CONFIG_MPC8555_CDS)
|
||||
/* Pre pciauto_bus_scan VIA init */
|
||||
mpc85xx_cds_enable_via(hose_a);
|
||||
#endif
|
||||
|
||||
hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
|
||||
|
||||
#if defined(CONFIG_MPC8555_CDS)
|
||||
/* Post pciauto_bus_scan VIA fixup */
|
||||
mpc85xx_cds_fixup_via(hose_a);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_85xx_PCI2
|
||||
hose_b = pcibios_alloc_controller();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* mf.c
|
||||
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
|
||||
* Copyright (C) 2004 Stephen Rothwell IBM Corporation
|
||||
* Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
|
||||
*
|
||||
* This modules exists as an interface between a Linux secondary partition
|
||||
* running on an iSeries and the primary partition's Virtual Service
|
||||
|
@ -36,10 +36,12 @@
|
|||
|
||||
#include <asm/time.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/paca.h>
|
||||
#include <asm/iSeries/vio.h>
|
||||
#include <asm/iSeries/mf.h>
|
||||
#include <asm/iSeries/HvLpConfig.h>
|
||||
#include <asm/iSeries/ItSpCommArea.h>
|
||||
#include <asm/iSeries/ItLpQueue.h>
|
||||
|
||||
/*
|
||||
* This is the structure layout for the Machine Facilites LPAR event
|
||||
|
@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
|
|||
complete(&rtc->com);
|
||||
}
|
||||
|
||||
int mf_get_rtc(struct rtc_time *tm)
|
||||
static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
|
||||
{
|
||||
struct ce_msg_comp_data ce_complete;
|
||||
struct rtc_time_data rtc_data;
|
||||
int rc;
|
||||
|
||||
memset(&ce_complete, 0, sizeof(ce_complete));
|
||||
memset(&rtc_data, 0, sizeof(rtc_data));
|
||||
init_completion(&rtc_data.com);
|
||||
ce_complete.handler = &get_rtc_time_complete;
|
||||
ce_complete.token = &rtc_data;
|
||||
rc = signal_ce_msg_simple(0x40, &ce_complete);
|
||||
if (rc)
|
||||
return rc;
|
||||
wait_for_completion(&rtc_data.com);
|
||||
tm->tm_wday = 0;
|
||||
tm->tm_yday = 0;
|
||||
tm->tm_isdst = 0;
|
||||
if (rtc_data.rc) {
|
||||
if (rc) {
|
||||
tm->tm_sec = 0;
|
||||
tm->tm_min = 0;
|
||||
tm->tm_hour = 0;
|
||||
tm->tm_mday = 15;
|
||||
tm->tm_mon = 5;
|
||||
tm->tm_year = 52;
|
||||
return rtc_data.rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) ||
|
||||
(rtc_data.ce_msg.ce_msg[2] == 0xaf)) {
|
||||
if ((ce_msg[2] == 0xa9) ||
|
||||
(ce_msg[2] == 0xaf)) {
|
||||
/* TOD clock is not set */
|
||||
tm->tm_sec = 1;
|
||||
tm->tm_min = 1;
|
||||
|
@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
|
|||
mf_set_rtc(tm);
|
||||
}
|
||||
{
|
||||
u8 *ce_msg = rtc_data.ce_msg.ce_msg;
|
||||
u8 year = ce_msg[5];
|
||||
u8 sec = ce_msg[6];
|
||||
u8 min = ce_msg[7];
|
||||
|
@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mf_get_rtc(struct rtc_time *tm)
|
||||
{
|
||||
struct ce_msg_comp_data ce_complete;
|
||||
struct rtc_time_data rtc_data;
|
||||
int rc;
|
||||
|
||||
memset(&ce_complete, 0, sizeof(ce_complete));
|
||||
memset(&rtc_data, 0, sizeof(rtc_data));
|
||||
init_completion(&rtc_data.com);
|
||||
ce_complete.handler = &get_rtc_time_complete;
|
||||
ce_complete.token = &rtc_data;
|
||||
rc = signal_ce_msg_simple(0x40, &ce_complete);
|
||||
if (rc)
|
||||
return rc;
|
||||
wait_for_completion(&rtc_data.com);
|
||||
return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
|
||||
}
|
||||
|
||||
struct boot_rtc_time_data {
|
||||
int busy;
|
||||
struct ce_msg_data ce_msg;
|
||||
int rc;
|
||||
};
|
||||
|
||||
static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
|
||||
{
|
||||
struct boot_rtc_time_data *rtc = token;
|
||||
|
||||
memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
|
||||
rtc->rc = 0;
|
||||
rtc->busy = 0;
|
||||
}
|
||||
|
||||
int mf_get_boot_rtc(struct rtc_time *tm)
|
||||
{
|
||||
struct ce_msg_comp_data ce_complete;
|
||||
struct boot_rtc_time_data rtc_data;
|
||||
int rc;
|
||||
|
||||
memset(&ce_complete, 0, sizeof(ce_complete));
|
||||
memset(&rtc_data, 0, sizeof(rtc_data));
|
||||
rtc_data.busy = 1;
|
||||
ce_complete.handler = &get_boot_rtc_time_complete;
|
||||
ce_complete.token = &rtc_data;
|
||||
rc = signal_ce_msg_simple(0x40, &ce_complete);
|
||||
if (rc)
|
||||
return rc;
|
||||
/* We need to poll here as we are not yet taking interrupts */
|
||||
while (rtc_data.busy) {
|
||||
extern unsigned long lpevent_count;
|
||||
struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
|
||||
if (lpq && ItLpQueue_isLpIntPending(lpq))
|
||||
lpevent_count += ItLpQueue_process(lpq, NULL);
|
||||
}
|
||||
return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
|
||||
}
|
||||
|
||||
int mf_set_rtc(struct rtc_time *tm)
|
||||
{
|
||||
char ce_time[12];
|
||||
|
|
|
@ -68,6 +68,7 @@ extern struct smp_ops_t *smp_ops;
|
|||
|
||||
static void (*pmac_tb_freeze)(int freeze);
|
||||
static struct device_node *pmac_tb_clock_chip_host;
|
||||
static u8 pmac_tb_pulsar_addr;
|
||||
static DEFINE_SPINLOCK(timebase_lock);
|
||||
static unsigned long timebase;
|
||||
|
||||
|
@ -106,12 +107,9 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
|
|||
u8 data;
|
||||
int rc;
|
||||
|
||||
/* Strangely, the device-tree says address is 0xd2, but darwin
|
||||
* accesses 0xd0 ...
|
||||
*/
|
||||
pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
|
||||
rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
|
||||
0xd4 | pmac_low_i2c_read,
|
||||
pmac_tb_pulsar_addr | pmac_low_i2c_read,
|
||||
0x2e, &data, 1);
|
||||
if (rc != 0)
|
||||
goto bail;
|
||||
|
@ -120,7 +118,7 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
|
|||
|
||||
pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
|
||||
rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
|
||||
0xd4 | pmac_low_i2c_write,
|
||||
pmac_tb_pulsar_addr | pmac_low_i2c_write,
|
||||
0x2e, &data, 1);
|
||||
bail:
|
||||
if (rc != 0) {
|
||||
|
@ -185,6 +183,12 @@ static int __init smp_core99_probe(void)
|
|||
if (ncpus <= 1)
|
||||
return 1;
|
||||
|
||||
/* HW sync only on these platforms */
|
||||
if (!machine_is_compatible("PowerMac7,2") &&
|
||||
!machine_is_compatible("PowerMac7,3") &&
|
||||
!machine_is_compatible("RackMac3,1"))
|
||||
goto nohwsync;
|
||||
|
||||
/* Look for the clock chip */
|
||||
for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
|
||||
struct device_node *p = of_get_parent(cc);
|
||||
|
@ -198,11 +202,18 @@ static int __init smp_core99_probe(void)
|
|||
goto next;
|
||||
switch (*reg) {
|
||||
case 0xd2:
|
||||
pmac_tb_freeze = smp_core99_cypress_tb_freeze;
|
||||
printk(KERN_INFO "Timebase clock is Cypress chip\n");
|
||||
if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
|
||||
pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
|
||||
pmac_tb_pulsar_addr = 0xd2;
|
||||
printk(KERN_INFO "Timebase clock is Pulsar chip\n");
|
||||
} else if (device_is_compatible(cc, "cy28508")) {
|
||||
pmac_tb_freeze = smp_core99_cypress_tb_freeze;
|
||||
printk(KERN_INFO "Timebase clock is Cypress chip\n");
|
||||
}
|
||||
break;
|
||||
case 0xd4:
|
||||
pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
|
||||
pmac_tb_pulsar_addr = 0xd4;
|
||||
printk(KERN_INFO "Timebase clock is Pulsar chip\n");
|
||||
break;
|
||||
}
|
||||
|
@ -210,12 +221,15 @@ static int __init smp_core99_probe(void)
|
|||
pmac_tb_clock_chip_host = p;
|
||||
smp_ops->give_timebase = smp_core99_give_timebase;
|
||||
smp_ops->take_timebase = smp_core99_take_timebase;
|
||||
of_node_put(cc);
|
||||
of_node_put(p);
|
||||
break;
|
||||
}
|
||||
next:
|
||||
of_node_put(p);
|
||||
}
|
||||
|
||||
nohwsync:
|
||||
mpic_request_ipis();
|
||||
|
||||
return ncpus;
|
||||
|
|
|
@ -1750,7 +1750,44 @@ static void __init flatten_device_tree(void)
|
|||
prom_printf("Device tree struct 0x%x -> 0x%x\n",
|
||||
RELOC(dt_struct_start), RELOC(dt_struct_end));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void __init fixup_device_tree(void)
|
||||
{
|
||||
unsigned long offset = reloc_offset();
|
||||
phandle u3, i2c, mpic;
|
||||
u32 u3_rev;
|
||||
u32 interrupts[2];
|
||||
u32 parent;
|
||||
|
||||
/* Some G5s have a missing interrupt definition, fix it up here */
|
||||
u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
|
||||
if ((long)u3 <= 0)
|
||||
return;
|
||||
i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
|
||||
if ((long)i2c <= 0)
|
||||
return;
|
||||
mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
|
||||
if ((long)mpic <= 0)
|
||||
return;
|
||||
|
||||
/* check if proper rev of u3 */
|
||||
if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0)
|
||||
return;
|
||||
if (u3_rev != 0x35)
|
||||
return;
|
||||
/* does it need fixup ? */
|
||||
if (prom_getproplen(i2c, "interrupts") > 0)
|
||||
return;
|
||||
/* interrupt on this revision of u3 is number 0 and level */
|
||||
interrupts[0] = 0;
|
||||
interrupts[1] = 1;
|
||||
prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
|
||||
parent = (u32)mpic;
|
||||
prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
|
||||
}
|
||||
|
||||
|
||||
static void __init prom_find_boot_cpu(void)
|
||||
{
|
||||
|
@ -1843,6 +1880,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
|
|||
prom_setprop(_prom->chosen, "linux,platform",
|
||||
&getprop_rval, sizeof(getprop_rval));
|
||||
|
||||
/*
|
||||
* On pSeries, inform the firmware about our capabilities
|
||||
*/
|
||||
if (RELOC(of_platform) & PLATFORM_PSERIES)
|
||||
prom_send_capabilities();
|
||||
|
||||
/*
|
||||
* On pSeries, copy the CPU hold code
|
||||
*/
|
||||
|
@ -1919,6 +1962,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
|
|||
PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixup any known bugs in the device-tree
|
||||
*/
|
||||
fixup_device_tree();
|
||||
|
||||
/*
|
||||
* Now finally create the flattened device-tree
|
||||
*/
|
||||
|
|
|
@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
|
|||
|
||||
void iSeries_get_boot_time(struct rtc_time *tm)
|
||||
{
|
||||
unsigned long time;
|
||||
static unsigned long lastsec = 1;
|
||||
|
||||
u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
|
||||
u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
|
||||
int year = 1970;
|
||||
int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
|
||||
int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
|
||||
int sec = ( dataWord1 >> 8 ) & 0x000000FF;
|
||||
int min = dataWord1 & 0x000000FF;
|
||||
int hour = ( dataWord2 >> 24 ) & 0x000000FF;
|
||||
int day = ( dataWord2 >> 8 ) & 0x000000FF;
|
||||
int mon = dataWord2 & 0x000000FF;
|
||||
|
||||
if ( piranha_simulator )
|
||||
return;
|
||||
|
||||
BCD_TO_BIN(sec);
|
||||
BCD_TO_BIN(min);
|
||||
BCD_TO_BIN(hour);
|
||||
BCD_TO_BIN(day);
|
||||
BCD_TO_BIN(mon);
|
||||
BCD_TO_BIN(year1);
|
||||
BCD_TO_BIN(year2);
|
||||
year = year1 * 100 + year2;
|
||||
|
||||
time = mktime(year, mon, day, hour, min, sec);
|
||||
time += ( jiffies / HZ );
|
||||
|
||||
/* Now THIS is a nasty hack!
|
||||
* It ensures that the first two calls get different answers.
|
||||
* That way the loop in init_time (time.c) will not think
|
||||
* the clock is stuck.
|
||||
*/
|
||||
if ( lastsec ) {
|
||||
time -= lastsec;
|
||||
--lastsec;
|
||||
}
|
||||
|
||||
to_tm(time, tm);
|
||||
tm->tm_year -= 1900;
|
||||
mf_get_boot_rtc(tm);
|
||||
tm->tm_mon -= 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -515,6 +515,7 @@ void __init time_init(void)
|
|||
do_gtod.varp = &do_gtod.vars[0];
|
||||
do_gtod.var_idx = 0;
|
||||
do_gtod.varp->tb_orig_stamp = tb_last_stamp;
|
||||
get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
|
||||
do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
|
||||
do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
|
||||
do_gtod.varp->tb_to_xs = tb_to_xs;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/pbm.h>
|
||||
|
||||
|
@ -379,6 +380,56 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct
|
|||
return PCI_DMA_ERROR_CODE;
|
||||
}
|
||||
|
||||
static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages)
|
||||
{
|
||||
int limit;
|
||||
|
||||
PCI_STC_FLUSHFLAG_INIT(strbuf);
|
||||
if (strbuf->strbuf_ctxflush &&
|
||||
iommu->iommu_ctxflush) {
|
||||
unsigned long matchreg, flushreg;
|
||||
|
||||
flushreg = strbuf->strbuf_ctxflush;
|
||||
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
|
||||
|
||||
limit = 100000;
|
||||
pci_iommu_write(flushreg, ctx);
|
||||
for(;;) {
|
||||
if (((long)pci_iommu_read(matchreg)) >= 0L)
|
||||
break;
|
||||
limit--;
|
||||
if (!limit)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (!limit)
|
||||
printk(KERN_WARNING "pci_strbuf_flush: ctx flush "
|
||||
"timeout vaddr[%08x] ctx[%lx]\n",
|
||||
vaddr, ctx);
|
||||
} else {
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
|
||||
pci_iommu_write(strbuf->strbuf_pflush, vaddr);
|
||||
}
|
||||
|
||||
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
|
||||
(void) pci_iommu_read(iommu->write_complete_reg);
|
||||
|
||||
limit = 100000;
|
||||
while (!PCI_STC_FLUSHFLAG_SET(strbuf)) {
|
||||
limit--;
|
||||
if (!limit)
|
||||
break;
|
||||
udelay(1);
|
||||
membar("#LoadLoad");
|
||||
}
|
||||
if (!limit)
|
||||
printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout "
|
||||
"vaddr[%08x] ctx[%lx] npages[%ld]\n",
|
||||
vaddr, ctx, npages);
|
||||
}
|
||||
|
||||
/* Unmap a single streaming mode DMA translation. */
|
||||
void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction)
|
||||
{
|
||||
|
@ -386,7 +437,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
|
|||
struct pci_iommu *iommu;
|
||||
struct pci_strbuf *strbuf;
|
||||
iopte_t *base;
|
||||
unsigned long flags, npages, i, ctx;
|
||||
unsigned long flags, npages, ctx;
|
||||
|
||||
if (direction == PCI_DMA_NONE)
|
||||
BUG();
|
||||
|
@ -414,29 +465,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int
|
|||
ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
|
||||
|
||||
/* Step 1: Kick data out of streaming buffers if necessary. */
|
||||
if (strbuf->strbuf_enabled) {
|
||||
u32 vaddr = bus_addr;
|
||||
|
||||
PCI_STC_FLUSHFLAG_INIT(strbuf);
|
||||
if (strbuf->strbuf_ctxflush &&
|
||||
iommu->iommu_ctxflush) {
|
||||
unsigned long matchreg, flushreg;
|
||||
|
||||
flushreg = strbuf->strbuf_ctxflush;
|
||||
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
|
||||
do {
|
||||
pci_iommu_write(flushreg, ctx);
|
||||
} while(((long)pci_iommu_read(matchreg)) < 0L);
|
||||
} else {
|
||||
for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
|
||||
pci_iommu_write(strbuf->strbuf_pflush, vaddr);
|
||||
}
|
||||
|
||||
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
|
||||
(void) pci_iommu_read(iommu->write_complete_reg);
|
||||
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
|
||||
membar("#LoadLoad");
|
||||
}
|
||||
if (strbuf->strbuf_enabled)
|
||||
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
|
||||
|
||||
/* Step 2: Clear out first TSB entry. */
|
||||
iopte_make_dummy(iommu, base);
|
||||
|
@ -647,29 +677,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
|
|||
ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL;
|
||||
|
||||
/* Step 1: Kick data out of streaming buffers if necessary. */
|
||||
if (strbuf->strbuf_enabled) {
|
||||
u32 vaddr = (u32) bus_addr;
|
||||
|
||||
PCI_STC_FLUSHFLAG_INIT(strbuf);
|
||||
if (strbuf->strbuf_ctxflush &&
|
||||
iommu->iommu_ctxflush) {
|
||||
unsigned long matchreg, flushreg;
|
||||
|
||||
flushreg = strbuf->strbuf_ctxflush;
|
||||
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
|
||||
do {
|
||||
pci_iommu_write(flushreg, ctx);
|
||||
} while(((long)pci_iommu_read(matchreg)) < 0L);
|
||||
} else {
|
||||
for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE)
|
||||
pci_iommu_write(strbuf->strbuf_pflush, vaddr);
|
||||
}
|
||||
|
||||
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
|
||||
(void) pci_iommu_read(iommu->write_complete_reg);
|
||||
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
|
||||
membar("#LoadLoad");
|
||||
}
|
||||
if (strbuf->strbuf_enabled)
|
||||
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
|
||||
|
||||
/* Step 2: Clear out first TSB entry. */
|
||||
iopte_make_dummy(iommu, base);
|
||||
|
@ -715,28 +724,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size
|
|||
}
|
||||
|
||||
/* Step 2: Kick data out of streaming buffers. */
|
||||
PCI_STC_FLUSHFLAG_INIT(strbuf);
|
||||
if (iommu->iommu_ctxflush &&
|
||||
strbuf->strbuf_ctxflush) {
|
||||
unsigned long matchreg, flushreg;
|
||||
|
||||
flushreg = strbuf->strbuf_ctxflush;
|
||||
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
|
||||
do {
|
||||
pci_iommu_write(flushreg, ctx);
|
||||
} while(((long)pci_iommu_read(matchreg)) < 0L);
|
||||
} else {
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
|
||||
pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
|
||||
}
|
||||
|
||||
/* Step 3: Perform flush synchronization sequence. */
|
||||
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
|
||||
(void) pci_iommu_read(iommu->write_complete_reg);
|
||||
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
|
||||
membar("#LoadLoad");
|
||||
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
|
||||
|
||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
}
|
||||
|
@ -749,7 +737,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
|
|||
struct pcidev_cookie *pcp;
|
||||
struct pci_iommu *iommu;
|
||||
struct pci_strbuf *strbuf;
|
||||
unsigned long flags, ctx;
|
||||
unsigned long flags, ctx, npages, i;
|
||||
u32 bus_addr;
|
||||
|
||||
pcp = pdev->sysdata;
|
||||
iommu = pcp->pbm->iommu;
|
||||
|
@ -772,36 +761,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i
|
|||
}
|
||||
|
||||
/* Step 2: Kick data out of streaming buffers. */
|
||||
PCI_STC_FLUSHFLAG_INIT(strbuf);
|
||||
if (iommu->iommu_ctxflush &&
|
||||
strbuf->strbuf_ctxflush) {
|
||||
unsigned long matchreg, flushreg;
|
||||
|
||||
flushreg = strbuf->strbuf_ctxflush;
|
||||
matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx);
|
||||
do {
|
||||
pci_iommu_write(flushreg, ctx);
|
||||
} while (((long)pci_iommu_read(matchreg)) < 0L);
|
||||
} else {
|
||||
unsigned long i, npages;
|
||||
u32 bus_addr;
|
||||
|
||||
bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
|
||||
|
||||
for(i = 1; i < nelems; i++)
|
||||
if (!sglist[i].dma_length)
|
||||
break;
|
||||
i--;
|
||||
npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT;
|
||||
for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE)
|
||||
pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
|
||||
}
|
||||
|
||||
/* Step 3: Perform flush synchronization sequence. */
|
||||
pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa);
|
||||
(void) pci_iommu_read(iommu->write_complete_reg);
|
||||
while (!PCI_STC_FLUSHFLAG_SET(strbuf))
|
||||
membar("#LoadLoad");
|
||||
bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
|
||||
for(i = 1; i < nelems; i++)
|
||||
if (!sglist[i].dma_length)
|
||||
break;
|
||||
i--;
|
||||
npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
|
||||
- bus_addr) >> IO_PAGE_SHIFT;
|
||||
pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages);
|
||||
|
||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
}
|
||||
|
|
|
@ -117,19 +117,34 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages
|
|||
|
||||
#define STRBUF_TAG_VALID 0x02UL
|
||||
|
||||
static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
|
||||
static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
|
||||
{
|
||||
unsigned long n;
|
||||
int limit;
|
||||
|
||||
iommu->strbuf_flushflag = 0UL;
|
||||
while (npages--)
|
||||
upa_writeq(base + (npages << IO_PAGE_SHIFT),
|
||||
n = npages;
|
||||
while (n--)
|
||||
upa_writeq(base + (n << IO_PAGE_SHIFT),
|
||||
iommu->strbuf_regs + STRBUF_PFLUSH);
|
||||
|
||||
/* Whoopee cushion! */
|
||||
upa_writeq(__pa(&iommu->strbuf_flushflag),
|
||||
iommu->strbuf_regs + STRBUF_FSYNC);
|
||||
upa_readq(iommu->sbus_control_reg);
|
||||
while (iommu->strbuf_flushflag == 0UL)
|
||||
|
||||
limit = 100000;
|
||||
while (iommu->strbuf_flushflag == 0UL) {
|
||||
limit--;
|
||||
if (!limit)
|
||||
break;
|
||||
udelay(1);
|
||||
membar("#LoadLoad");
|
||||
}
|
||||
if (!limit)
|
||||
printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout "
|
||||
"vaddr[%08x] npages[%ld]\n",
|
||||
base, npages);
|
||||
}
|
||||
|
||||
static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
|
||||
|
@ -406,7 +421,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size,
|
|||
|
||||
spin_lock_irqsave(&iommu->lock, flags);
|
||||
free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
|
||||
strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
|
||||
sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);
|
||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
}
|
||||
|
||||
|
@ -569,7 +584,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int
|
|||
iommu = sdev->bus->iommu;
|
||||
spin_lock_irqsave(&iommu->lock, flags);
|
||||
free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
|
||||
strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
|
||||
sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT);
|
||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
}
|
||||
|
||||
|
@ -581,7 +596,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t
|
|||
size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
|
||||
|
||||
spin_lock_irqsave(&iommu->lock, flags);
|
||||
strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
|
||||
sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT);
|
||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
}
|
||||
|
||||
|
@ -605,7 +620,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int
|
|||
size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
|
||||
|
||||
spin_lock_irqsave(&iommu->lock, flags);
|
||||
strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
|
||||
sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT);
|
||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -383,6 +383,17 @@ static void __init process_switch(char c)
|
|||
/* Use PROM debug console. */
|
||||
register_console(&prom_debug_console);
|
||||
break;
|
||||
case 'P':
|
||||
/* Force UltraSPARC-III P-Cache on. */
|
||||
if (tlb_type != cheetah) {
|
||||
printk("BOOT: Ignoring P-Cache force option.\n");
|
||||
break;
|
||||
}
|
||||
cheetah_pcache_forced_on = 1;
|
||||
add_taint(TAINT_MACHINE_CHECK);
|
||||
cheetah_enable_pcache();
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("Unknown boot switch (-%c)\n", c);
|
||||
break;
|
||||
|
|
|
@ -123,6 +123,9 @@ void __init smp_callin(void)
|
|||
|
||||
smp_setup_percpu_timer();
|
||||
|
||||
if (cheetah_pcache_forced_on)
|
||||
cheetah_enable_pcache();
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
calibrate_delay();
|
||||
|
|
|
@ -421,6 +421,25 @@ asmlinkage void cee_log(unsigned long ce_status,
|
|||
}
|
||||
}
|
||||
|
||||
int cheetah_pcache_forced_on;
|
||||
|
||||
void cheetah_enable_pcache(void)
|
||||
{
|
||||
unsigned long dcr;
|
||||
|
||||
printk("CHEETAH: Enabling P-Cache on cpu %d.\n",
|
||||
smp_processor_id());
|
||||
|
||||
__asm__ __volatile__("ldxa [%%g0] %1, %0"
|
||||
: "=r" (dcr)
|
||||
: "i" (ASI_DCU_CONTROL_REG));
|
||||
dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL);
|
||||
__asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: /* no outputs */
|
||||
: "r" (dcr), "i" (ASI_DCU_CONTROL_REG));
|
||||
}
|
||||
|
||||
/* Cheetah error trap handling. */
|
||||
static unsigned long ecache_flush_physbase;
|
||||
static unsigned long ecache_flush_linesize;
|
||||
|
|
|
@ -2,10 +2,6 @@ menu "Kernel hacking"
|
|||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config FRAME_POINTER
|
||||
bool
|
||||
default y if DEBUG_INFO
|
||||
|
||||
config PT_PROXY
|
||||
bool "Enable ptrace proxy"
|
||||
depends on XTERM_CHAN && DEBUG_INFO && MODE_TT
|
||||
|
|
|
@ -6,6 +6,10 @@ config 64BIT
|
|||
bool
|
||||
default y
|
||||
|
||||
config TOP_ADDR
|
||||
hex
|
||||
default 0x80000000
|
||||
|
||||
config 3_LEVEL_PGTABLES
|
||||
bool
|
||||
default y
|
||||
|
|
|
@ -20,9 +20,17 @@
|
|||
#include "os.h"
|
||||
|
||||
#ifdef CONFIG_NOCONFIG_CHAN
|
||||
|
||||
/* The printk's here are wrong because we are complaining that there is no
|
||||
* output device, but printk is printing to that output device. The user will
|
||||
* never see the error. printf would be better, except it can't run on a
|
||||
* kernel stack because it will overflow it.
|
||||
* Use printk for now since that will avoid crashing.
|
||||
*/
|
||||
|
||||
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(NULL);
|
||||
}
|
||||
|
@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
|
|||
static int not_configged_open(int input, int output, int primary, void *data,
|
||||
char **dev_out)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-ENODEV);
|
||||
}
|
||||
|
||||
static void not_configged_close(int fd, void *data)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
}
|
||||
|
||||
static int not_configged_read(int fd, char *c_out, void *data)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-EIO);
|
||||
}
|
||||
|
||||
static int not_configged_write(int fd, const char *buf, int len, void *data)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-EIO);
|
||||
}
|
||||
|
@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
|
|||
static int not_configged_console_write(int fd, const char *buf, int len,
|
||||
void *data)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-EIO);
|
||||
}
|
||||
|
@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len,
|
|||
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
|
||||
unsigned short *cols)
|
||||
{
|
||||
printf(KERN_ERR "Using a channel type which is configured out of "
|
||||
printk(KERN_ERR "Using a channel type which is configured out of "
|
||||
"UML\n");
|
||||
return(-ENODEV);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data)
|
|||
struct mcast_init *init = data;
|
||||
char *port_str = NULL, *ttl_str = NULL, *remain;
|
||||
char *last;
|
||||
int n;
|
||||
|
||||
*init = ((struct mcast_init)
|
||||
{ .addr = "239.192.168.1",
|
||||
|
@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data)
|
|||
}
|
||||
|
||||
if(port_str != NULL){
|
||||
n = simple_strtoul(port_str, &last, 10);
|
||||
init->port = simple_strtoul(port_str, &last, 10);
|
||||
if((*last != '\0') || (last == port_str)){
|
||||
printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
|
||||
port_str);
|
||||
return(0);
|
||||
}
|
||||
init->port = htons(n);
|
||||
}
|
||||
|
||||
if(ttl_str != NULL){
|
||||
|
|
|
@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
|
|||
}
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = in_aton(addr);
|
||||
sin->sin_port = port;
|
||||
sin->sin_port = htons(port);
|
||||
return(sin);
|
||||
}
|
||||
|
||||
|
@ -55,28 +55,25 @@ static int mcast_open(void *data)
|
|||
struct mcast_data *pri = data;
|
||||
struct sockaddr_in *sin = pri->mcast_addr;
|
||||
struct ip_mreq mreq;
|
||||
int fd, yes = 1;
|
||||
int fd = -EINVAL, yes = 1, err = -EINVAL;;
|
||||
|
||||
|
||||
if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
|
||||
fd = -EINVAL;
|
||||
if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
|
||||
goto out;
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (fd < 0){
|
||||
printk("mcast_open : data socket failed, errno = %d\n",
|
||||
errno);
|
||||
fd = -ENOMEM;
|
||||
fd = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
|
||||
printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
|
||||
errno);
|
||||
os_close_file(fd);
|
||||
fd = -EINVAL;
|
||||
goto out;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
/* set ttl according to config */
|
||||
|
@ -84,26 +81,20 @@ static int mcast_open(void *data)
|
|||
sizeof(pri->ttl)) < 0) {
|
||||
printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
|
||||
errno);
|
||||
os_close_file(fd);
|
||||
fd = -EINVAL;
|
||||
goto out;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
/* set LOOP, so data does get fed back to local sockets */
|
||||
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
|
||||
printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
|
||||
errno);
|
||||
os_close_file(fd);
|
||||
fd = -EINVAL;
|
||||
goto out;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
/* bind socket to mcast address */
|
||||
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
|
||||
printk("mcast_open : data bind failed, errno = %d\n", errno);
|
||||
os_close_file(fd);
|
||||
fd = -EINVAL;
|
||||
goto out;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
/* subscribe to the multicast group */
|
||||
|
@ -117,12 +108,15 @@ static int mcast_open(void *data)
|
|||
"interface on the host.\n");
|
||||
printk("eth0 should be configured in order to use the "
|
||||
"multicast transport.\n");
|
||||
os_close_file(fd);
|
||||
fd = -EINVAL;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
out:
|
||||
return(fd);
|
||||
return fd;
|
||||
|
||||
out_close:
|
||||
os_close_file(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mcast_close(int fd, void *data)
|
||||
|
@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = {
|
|||
.delete_address = NULL,
|
||||
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
|
||||
};
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
/* Much of this ripped from hw_random.c */
|
||||
|
||||
/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
|
||||
/* Much of this ripped from drivers/char/hw_random.c, see there for other
|
||||
* copyright.
|
||||
*
|
||||
* This software may be used and distributed according to the terms
|
||||
* of the GNU General Public License, incorporated herein by reference.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
|
@ -12,8 +17,6 @@
|
|||
*/
|
||||
#define RNG_VERSION "1.0.0"
|
||||
#define RNG_MODULE_NAME "random"
|
||||
#define RNG_DRIVER_NAME RNG_MODULE_NAME " virtual driver " RNG_VERSION
|
||||
#define PFX RNG_MODULE_NAME ": "
|
||||
|
||||
#define RNG_MISCDEV_MINOR 183 /* official */
|
||||
|
||||
|
@ -98,7 +101,7 @@ static int __init rng_init (void)
|
|||
|
||||
err = misc_register (&rng_miscdev);
|
||||
if (err) {
|
||||
printk (KERN_ERR PFX "misc device register failed\n");
|
||||
printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
|
||||
goto err_out_cleanup_hw;
|
||||
}
|
||||
|
||||
|
@ -120,3 +123,6 @@ static void __exit rng_cleanup (void)
|
|||
|
||||
module_init (rng_init);
|
||||
module_exit (rng_cleanup);
|
||||
|
||||
MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "init.h"
|
||||
#include "irq_user.h"
|
||||
#include "mconsole_kern.h"
|
||||
#include "2_5compat.h"
|
||||
|
||||
static int ssl_version = 1;
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "irq_user.h"
|
||||
#include "mconsole_kern.h"
|
||||
#include "init.h"
|
||||
#include "2_5compat.h"
|
||||
|
||||
#define MAX_TTYS (16)
|
||||
|
||||
|
|
|
@ -49,13 +49,12 @@
|
|||
#include "irq_user.h"
|
||||
#include "irq_kern.h"
|
||||
#include "ubd_user.h"
|
||||
#include "2_5compat.h"
|
||||
#include "os.h"
|
||||
#include "mem.h"
|
||||
#include "mem_kern.h"
|
||||
#include "cow.h"
|
||||
|
||||
enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
|
||||
enum ubd_req { UBD_READ, UBD_WRITE };
|
||||
|
||||
struct io_thread_req {
|
||||
enum ubd_req op;
|
||||
|
@ -68,8 +67,6 @@ struct io_thread_req {
|
|||
unsigned long sector_mask;
|
||||
unsigned long long cow_offset;
|
||||
unsigned long bitmap_words[2];
|
||||
int map_fd;
|
||||
unsigned long long map_offset;
|
||||
int error;
|
||||
};
|
||||
|
||||
|
@ -122,10 +119,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
|
|||
|
||||
#define MAX_DEV (8)
|
||||
|
||||
/* Changed in early boot */
|
||||
static int ubd_do_mmap = 0;
|
||||
#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
|
||||
|
||||
static struct block_device_operations ubd_blops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ubd_open,
|
||||
|
@ -175,12 +168,6 @@ struct ubd {
|
|||
int no_cow;
|
||||
struct cow cow;
|
||||
struct platform_device pdev;
|
||||
|
||||
int map_writes;
|
||||
int map_reads;
|
||||
int nomap_writes;
|
||||
int nomap_reads;
|
||||
int write_maps;
|
||||
};
|
||||
|
||||
#define DEFAULT_COW { \
|
||||
|
@ -200,11 +187,6 @@ struct ubd {
|
|||
.openflags = OPEN_FLAGS, \
|
||||
.no_cow = 0, \
|
||||
.cow = DEFAULT_COW, \
|
||||
.map_writes = 0, \
|
||||
.map_reads = 0, \
|
||||
.nomap_writes = 0, \
|
||||
.nomap_reads = 0, \
|
||||
.write_maps = 0, \
|
||||
}
|
||||
|
||||
struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
|
||||
|
@ -314,13 +296,6 @@ static int ubd_setup_common(char *str, int *index_out)
|
|||
int major;
|
||||
|
||||
str++;
|
||||
if(!strcmp(str, "mmap")){
|
||||
CHOOSE_MODE(printk("mmap not supported by the ubd "
|
||||
"driver in tt mode\n"),
|
||||
ubd_do_mmap = 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(!strcmp(str, "sync")){
|
||||
global_openflags = of_sync(global_openflags);
|
||||
return(0);
|
||||
|
@ -464,9 +439,9 @@ static int udb_setup(char *str)
|
|||
__setup("udb", udb_setup);
|
||||
__uml_help(udb_setup,
|
||||
"udb\n"
|
||||
" This option is here solely to catch ubd -> udb typos, which can be\n\n"
|
||||
" to impossible to catch visually unless you specifically look for\n\n"
|
||||
" them. The only result of any option starting with 'udb' is an error\n\n"
|
||||
" This option is here solely to catch ubd -> udb typos, which can be\n"
|
||||
" to impossible to catch visually unless you specifically look for\n"
|
||||
" them. The only result of any option starting with 'udb' is an error\n"
|
||||
" in the boot output.\n\n"
|
||||
);
|
||||
|
||||
|
@ -524,7 +499,7 @@ static void ubd_handler(void)
|
|||
{
|
||||
struct io_thread_req req;
|
||||
struct request *rq = elv_next_request(ubd_queue);
|
||||
int n, err;
|
||||
int n;
|
||||
|
||||
do_ubd = NULL;
|
||||
intr_count++;
|
||||
|
@ -538,19 +513,6 @@ static void ubd_handler(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if((req.op != UBD_MMAP) &&
|
||||
((req.offset != ((__u64) (rq->sector)) << 9) ||
|
||||
(req.length != (rq->current_nr_sectors) << 9)))
|
||||
panic("I/O op mismatch");
|
||||
|
||||
if(req.map_fd != -1){
|
||||
err = physmem_subst_mapping(req.buffer, req.map_fd,
|
||||
req.map_offset, 1);
|
||||
if(err)
|
||||
printk("ubd_handler - physmem_subst_mapping failed, "
|
||||
"err = %d\n", -err);
|
||||
}
|
||||
|
||||
ubd_finish(rq, req.error);
|
||||
reactivate_fd(thread_fd, UBD_IRQ);
|
||||
do_ubd_request(ubd_queue);
|
||||
|
@ -583,14 +545,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out)
|
|||
|
||||
static void ubd_close(struct ubd *dev)
|
||||
{
|
||||
if(ubd_do_mmap)
|
||||
physmem_forget_descriptor(dev->fd);
|
||||
os_close_file(dev->fd);
|
||||
if(dev->cow.file == NULL)
|
||||
return;
|
||||
|
||||
if(ubd_do_mmap)
|
||||
physmem_forget_descriptor(dev->cow.fd);
|
||||
os_close_file(dev->cow.fd);
|
||||
vfree(dev->cow.bitmap);
|
||||
dev->cow.bitmap = NULL;
|
||||
|
@ -1010,94 +968,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
|
|||
req->bitmap_words, bitmap_len);
|
||||
}
|
||||
|
||||
static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
|
||||
{
|
||||
__u64 sector;
|
||||
unsigned char *bitmap;
|
||||
int bit, i;
|
||||
|
||||
/* mmap must have been requested on the command line */
|
||||
if(!ubd_do_mmap)
|
||||
return(-1);
|
||||
|
||||
/* The buffer must be page aligned */
|
||||
if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
|
||||
return(-1);
|
||||
|
||||
/* The request must be a page long */
|
||||
if((req->current_nr_sectors << 9) != PAGE_SIZE)
|
||||
return(-1);
|
||||
|
||||
if(dev->cow.file == NULL)
|
||||
return(dev->fd);
|
||||
|
||||
sector = offset >> 9;
|
||||
bitmap = (unsigned char *) dev->cow.bitmap;
|
||||
bit = ubd_test_bit(sector, bitmap);
|
||||
|
||||
for(i = 1; i < req->current_nr_sectors; i++){
|
||||
if(ubd_test_bit(sector + i, bitmap) != bit)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(bit || (rq_data_dir(req) == WRITE))
|
||||
offset += dev->cow.data_offset;
|
||||
|
||||
/* The data on disk must be page aligned */
|
||||
if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
|
||||
return(-1);
|
||||
|
||||
return(bit ? dev->fd : dev->cow.fd);
|
||||
}
|
||||
|
||||
static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
|
||||
struct request *req,
|
||||
struct io_thread_req *io_req)
|
||||
{
|
||||
int err;
|
||||
|
||||
if(rq_data_dir(req) == WRITE){
|
||||
/* Writes are almost no-ops since the new data is already in the
|
||||
* host page cache
|
||||
*/
|
||||
dev->map_writes++;
|
||||
if(dev->cow.file != NULL)
|
||||
cowify_bitmap(io_req->offset, io_req->length,
|
||||
&io_req->sector_mask, &io_req->cow_offset,
|
||||
dev->cow.bitmap, dev->cow.bitmap_offset,
|
||||
io_req->bitmap_words,
|
||||
dev->cow.bitmap_len);
|
||||
}
|
||||
else {
|
||||
int w;
|
||||
|
||||
if((dev->cow.file != NULL) && (fd == dev->cow.fd))
|
||||
w = 0;
|
||||
else w = dev->openflags.w;
|
||||
|
||||
if((dev->cow.file != NULL) && (fd == dev->fd))
|
||||
offset += dev->cow.data_offset;
|
||||
|
||||
err = physmem_subst_mapping(req->buffer, fd, offset, w);
|
||||
if(err){
|
||||
printk("physmem_subst_mapping failed, err = %d\n",
|
||||
-err);
|
||||
return(1);
|
||||
}
|
||||
dev->map_reads++;
|
||||
}
|
||||
io_req->op = UBD_MMAP;
|
||||
io_req->buffer = req->buffer;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Called with ubd_io_lock held */
|
||||
static int prepare_request(struct request *req, struct io_thread_req *io_req)
|
||||
{
|
||||
struct gendisk *disk = req->rq_disk;
|
||||
struct ubd *dev = disk->private_data;
|
||||
__u64 offset;
|
||||
int len, fd;
|
||||
int len;
|
||||
|
||||
if(req->rq_status == RQ_INACTIVE) return(1);
|
||||
|
||||
|
@ -1114,34 +991,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
|
|||
|
||||
io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
|
||||
io_req->fds[1] = dev->fd;
|
||||
io_req->map_fd = -1;
|
||||
io_req->cow_offset = -1;
|
||||
io_req->offset = offset;
|
||||
io_req->length = len;
|
||||
io_req->error = 0;
|
||||
io_req->sector_mask = 0;
|
||||
|
||||
fd = mmap_fd(req, dev, io_req->offset);
|
||||
if(fd > 0){
|
||||
/* If mmapping is otherwise OK, but the first access to the
|
||||
* page is a write, then it's not mapped in yet. So we have
|
||||
* to write the data to disk first, then we can map the disk
|
||||
* page in and continue normally from there.
|
||||
*/
|
||||
if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
|
||||
io_req->map_fd = dev->fd;
|
||||
io_req->map_offset = io_req->offset +
|
||||
dev->cow.data_offset;
|
||||
dev->write_maps++;
|
||||
}
|
||||
else return(prepare_mmap_request(dev, fd, io_req->offset, req,
|
||||
io_req));
|
||||
}
|
||||
|
||||
if(rq_data_dir(req) == READ)
|
||||
dev->nomap_reads++;
|
||||
else dev->nomap_writes++;
|
||||
|
||||
io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
|
||||
io_req->offsets[0] = 0;
|
||||
io_req->offsets[1] = dev->cow.data_offset;
|
||||
|
@ -1229,143 +1084,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
|
|||
return(-EINVAL);
|
||||
}
|
||||
|
||||
static int ubd_check_remapped(int fd, unsigned long address, int is_write,
|
||||
__u64 offset)
|
||||
{
|
||||
__u64 bitmap_offset;
|
||||
unsigned long new_bitmap[2];
|
||||
int i, err, n;
|
||||
|
||||
/* If it's not a write access, we can't do anything about it */
|
||||
if(!is_write)
|
||||
return(0);
|
||||
|
||||
/* We have a write */
|
||||
for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
|
||||
struct ubd *dev = &ubd_dev[i];
|
||||
|
||||
if((dev->fd != fd) && (dev->cow.fd != fd))
|
||||
continue;
|
||||
|
||||
/* It's a write to a ubd device */
|
||||
|
||||
/* This should be impossible now */
|
||||
if(!dev->openflags.w){
|
||||
/* It's a write access on a read-only device - probably
|
||||
* shouldn't happen. If the kernel is trying to change
|
||||
* something with no intention of writing it back out,
|
||||
* then this message will clue us in that this needs
|
||||
* fixing
|
||||
*/
|
||||
printk("Write access to mapped page from readonly ubd "
|
||||
"device %d\n", i);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* It's a write to a writeable ubd device - it must be COWed
|
||||
* because, otherwise, the page would have been mapped in
|
||||
* writeable
|
||||
*/
|
||||
|
||||
if(!dev->cow.file)
|
||||
panic("Write fault on writeable non-COW ubd device %d",
|
||||
i);
|
||||
|
||||
/* It should also be an access to the backing file since the
|
||||
* COW pages should be mapped in read-write
|
||||
*/
|
||||
|
||||
if(fd == dev->fd)
|
||||
panic("Write fault on a backing page of ubd "
|
||||
"device %d\n", i);
|
||||
|
||||
/* So, we do the write, copying the backing data to the COW
|
||||
* file...
|
||||
*/
|
||||
|
||||
err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
|
||||
if(err < 0)
|
||||
panic("Couldn't seek to %lld in COW file of ubd "
|
||||
"device %d, err = %d",
|
||||
offset + dev->cow.data_offset, i, -err);
|
||||
|
||||
n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
|
||||
if(n != PAGE_SIZE)
|
||||
panic("Couldn't copy data to COW file of ubd "
|
||||
"device %d, err = %d", i, -n);
|
||||
|
||||
/* ... updating the COW bitmap... */
|
||||
|
||||
cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
|
||||
dev->cow.bitmap, dev->cow.bitmap_offset,
|
||||
new_bitmap, dev->cow.bitmap_len);
|
||||
|
||||
err = os_seek_file(dev->fd, bitmap_offset);
|
||||
if(err < 0)
|
||||
panic("Couldn't seek to %lld in COW file of ubd "
|
||||
"device %d, err = %d", bitmap_offset, i, -err);
|
||||
|
||||
n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
|
||||
if(n != sizeof(new_bitmap))
|
||||
panic("Couldn't update bitmap of ubd device %d, "
|
||||
"err = %d", i, -n);
|
||||
|
||||
/* Maybe we can map the COW page in, and maybe we can't. If
|
||||
* it is a pre-V3 COW file, we can't, since the alignment will
|
||||
* be wrong. If it is a V3 or later COW file which has been
|
||||
* moved to a system with a larger page size, then maybe we
|
||||
* can't, depending on the exact location of the page.
|
||||
*/
|
||||
|
||||
offset += dev->cow.data_offset;
|
||||
|
||||
/* Remove the remapping, putting the original anonymous page
|
||||
* back. If the COW file can be mapped in, that is done.
|
||||
* Otherwise, the COW page is read in.
|
||||
*/
|
||||
|
||||
if(!physmem_remove_mapping((void *) address))
|
||||
panic("Address 0x%lx not remapped by ubd device %d",
|
||||
address, i);
|
||||
if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
|
||||
physmem_subst_mapping((void *) address, dev->fd,
|
||||
offset, 1);
|
||||
else {
|
||||
err = os_seek_file(dev->fd, offset);
|
||||
if(err < 0)
|
||||
panic("Couldn't seek to %lld in COW file of "
|
||||
"ubd device %d, err = %d", offset, i,
|
||||
-err);
|
||||
|
||||
n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
|
||||
if(n != PAGE_SIZE)
|
||||
panic("Failed to read page from offset %llx of "
|
||||
"COW file of ubd device %d, err = %d",
|
||||
offset, i, -n);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* It's not a write on a ubd device */
|
||||
return(0);
|
||||
}
|
||||
|
||||
static struct remapper ubd_remapper = {
|
||||
.list = LIST_HEAD_INIT(ubd_remapper.list),
|
||||
.proc = ubd_check_remapped,
|
||||
};
|
||||
|
||||
static int ubd_remapper_setup(void)
|
||||
{
|
||||
if(ubd_do_mmap)
|
||||
register_remapper(&ubd_remapper);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
__initcall(ubd_remapper_setup);
|
||||
|
||||
static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
|
||||
{
|
||||
struct uml_stat buf1, buf2;
|
||||
|
@ -1568,15 +1286,6 @@ void do_io(struct io_thread_req *req)
|
|||
int err;
|
||||
__u64 off;
|
||||
|
||||
if(req->op == UBD_MMAP){
|
||||
/* Touch the page to force the host to do any necessary IO to
|
||||
* get it into memory
|
||||
*/
|
||||
n = *((volatile int *) req->buffer);
|
||||
req->error = update_bitmap(req);
|
||||
return;
|
||||
}
|
||||
|
||||
nsectors = req->length / req->sectorsize;
|
||||
start = 0;
|
||||
do {
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#ifndef __2_5_COMPAT_H__
|
||||
#define __2_5_COMPAT_H__
|
||||
|
||||
#define INIT_HARDSECT(arr, maj, sizes)
|
||||
|
||||
#define SET_PRI(task) do ; while(0)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
|
@ -31,7 +31,6 @@ extern int sysemu_supported;
|
|||
#ifdef UML_CONFIG_MODE_SKAS
|
||||
|
||||
#include "skas_ptregs.h"
|
||||
#include "sysdep/faultinfo.h"
|
||||
|
||||
#define REGS_IP(r) ((r)[HOST_IP])
|
||||
#define REGS_SP(r) ((r)[HOST_SP])
|
||||
|
@ -59,6 +58,7 @@ extern int sysemu_supported;
|
|||
#define PTRACE_SYSEMU_SINGLESTEP 32
|
||||
#endif
|
||||
|
||||
#include "sysdep/faultinfo.h"
|
||||
#include "choose-mode.h"
|
||||
|
||||
union uml_pt_regs {
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include "linux/in6.h"
|
||||
#include "asm/uaccess.h"
|
||||
|
||||
extern unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, int len,
|
||||
int sum, int *err_ptr);
|
||||
extern unsigned csum_partial(const unsigned char *buff, unsigned len,
|
||||
unsigned sum);
|
||||
|
||||
|
@ -31,10 +29,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
|
|||
}
|
||||
|
||||
static __inline__
|
||||
unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
|
||||
int len, int sum, int *err_ptr)
|
||||
unsigned int csum_partial_copy_from_user(const unsigned char *src,
|
||||
unsigned char *dst, int len, int sum,
|
||||
int *err_ptr)
|
||||
{
|
||||
return csum_partial_copy_from(src, dst, len, sum, err_ptr);
|
||||
if(copy_from_user(dst, src, len)){
|
||||
*err_ptr = -EFAULT;
|
||||
return(-1);
|
||||
}
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,15 +140,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b)
|
|||
return a;
|
||||
}
|
||||
|
||||
#endif
|
||||
extern unsigned short ip_compute_csum(unsigned char * buff, int len);
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
#endif
|
||||
|
|
|
@ -135,6 +135,7 @@ extern int mode_tt;
|
|||
__CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
|
||||
#define UPT_SC(r) ((r)->tt.sc)
|
||||
#define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
|
||||
#define UPT_SYSCALL_RET(r) UPT_RAX(r)
|
||||
|
||||
extern int user_context(unsigned long sp);
|
||||
|
||||
|
@ -196,32 +197,32 @@ struct syscall_args {
|
|||
|
||||
|
||||
#define UPT_SET(regs, reg, val) \
|
||||
({ unsigned long val; \
|
||||
({ unsigned long __upt_val = val; \
|
||||
switch(reg){ \
|
||||
case R8: UPT_R8(regs) = val; break; \
|
||||
case R9: UPT_R9(regs) = val; break; \
|
||||
case R10: UPT_R10(regs) = val; break; \
|
||||
case R11: UPT_R11(regs) = val; break; \
|
||||
case R12: UPT_R12(regs) = val; break; \
|
||||
case R13: UPT_R13(regs) = val; break; \
|
||||
case R14: UPT_R14(regs) = val; break; \
|
||||
case R15: UPT_R15(regs) = val; break; \
|
||||
case RIP: UPT_IP(regs) = val; break; \
|
||||
case RSP: UPT_SP(regs) = val; break; \
|
||||
case RAX: UPT_RAX(regs) = val; break; \
|
||||
case RBX: UPT_RBX(regs) = val; break; \
|
||||
case RCX: UPT_RCX(regs) = val; break; \
|
||||
case RDX: UPT_RDX(regs) = val; break; \
|
||||
case RSI: UPT_RSI(regs) = val; break; \
|
||||
case RDI: UPT_RDI(regs) = val; break; \
|
||||
case RBP: UPT_RBP(regs) = val; break; \
|
||||
case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \
|
||||
case CS: UPT_CS(regs) = val; break; \
|
||||
case DS: UPT_DS(regs) = val; break; \
|
||||
case ES: UPT_ES(regs) = val; break; \
|
||||
case FS: UPT_FS(regs) = val; break; \
|
||||
case GS: UPT_GS(regs) = val; break; \
|
||||
case EFLAGS: UPT_EFLAGS(regs) = val; break; \
|
||||
case R8: UPT_R8(regs) = __upt_val; break; \
|
||||
case R9: UPT_R9(regs) = __upt_val; break; \
|
||||
case R10: UPT_R10(regs) = __upt_val; break; \
|
||||
case R11: UPT_R11(regs) = __upt_val; break; \
|
||||
case R12: UPT_R12(regs) = __upt_val; break; \
|
||||
case R13: UPT_R13(regs) = __upt_val; break; \
|
||||
case R14: UPT_R14(regs) = __upt_val; break; \
|
||||
case R15: UPT_R15(regs) = __upt_val; break; \
|
||||
case RIP: UPT_IP(regs) = __upt_val; break; \
|
||||
case RSP: UPT_SP(regs) = __upt_val; break; \
|
||||
case RAX: UPT_RAX(regs) = __upt_val; break; \
|
||||
case RBX: UPT_RBX(regs) = __upt_val; break; \
|
||||
case RCX: UPT_RCX(regs) = __upt_val; break; \
|
||||
case RDX: UPT_RDX(regs) = __upt_val; break; \
|
||||
case RSI: UPT_RSI(regs) = __upt_val; break; \
|
||||
case RDI: UPT_RDI(regs) = __upt_val; break; \
|
||||
case RBP: UPT_RBP(regs) = __upt_val; break; \
|
||||
case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
|
||||
case CS: UPT_CS(regs) = __upt_val; break; \
|
||||
case DS: UPT_DS(regs) = __upt_val; break; \
|
||||
case ES: UPT_ES(regs) = __upt_val; break; \
|
||||
case FS: UPT_FS(regs) = __upt_val; break; \
|
||||
case GS: UPT_GS(regs) = __upt_val; break; \
|
||||
case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
|
||||
default : \
|
||||
panic("Bad register in UPT_SET : %d\n", reg); \
|
||||
break; \
|
||||
|
@ -245,14 +246,3 @@ struct syscall_args {
|
|||
CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __UM_SYSRQ_H
|
||||
#define __UM_SYSRQ_H
|
||||
|
||||
extern void show_trace(unsigned long *stack);
|
||||
struct task_struct;
|
||||
extern void show_trace(struct task_struct* task, unsigned long *stack);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,7 @@ obj-y = config.o exec_kern.o exitcode.o \
|
|||
tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
|
||||
user_util.o
|
||||
|
||||
obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
|
||||
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
|
||||
obj-$(CONFIG_GPROF) += gprof_syms.o
|
||||
obj-$(CONFIG_GCOV) += gmon_syms.o
|
||||
obj-$(CONFIG_TTY_LOG) += tty_log.o
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "kern.h"
|
||||
#include "irq_user.h"
|
||||
#include "tlb.h"
|
||||
#include "2_5compat.h"
|
||||
#include "os.h"
|
||||
#include "time_user.h"
|
||||
#include "choose-mode.h"
|
||||
|
|
|
@ -41,12 +41,31 @@ static int __init uml_initrd_setup(char *line, int *add)
|
|||
return 0;
|
||||
}
|
||||
|
||||
__uml_setup("initrd=", uml_initrd_setup,
|
||||
__uml_setup("initrd=", uml_initrd_setup,
|
||||
"initrd=<initrd image>\n"
|
||||
" This is used to boot UML from an initrd image. The argument is the\n"
|
||||
" name of the file containing the image.\n\n"
|
||||
);
|
||||
|
||||
int load_initrd(char *filename, void *buf, int size)
|
||||
{
|
||||
int fd, n;
|
||||
|
||||
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
|
||||
if(fd < 0){
|
||||
printk("Opening '%s' failed - err = %d\n", filename, -fd);
|
||||
return(-1);
|
||||
}
|
||||
n = os_read_file(fd, buf, size);
|
||||
if(n != size){
|
||||
printk("Read of %d bytes from '%s' failed, err = %d\n", size,
|
||||
filename, -n);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
os_close_file(fd);
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "user_util.h"
|
||||
#include "kern_util.h"
|
||||
#include "user.h"
|
||||
#include "initrd.h"
|
||||
#include "os.h"
|
||||
|
||||
int load_initrd(char *filename, void *buf, int size)
|
||||
{
|
||||
int fd, n;
|
||||
|
||||
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
|
||||
if(fd < 0){
|
||||
printk("Opening '%s' failed - err = %d\n", filename, -fd);
|
||||
return(-1);
|
||||
}
|
||||
n = os_read_file(fd, buf, size);
|
||||
if(n != size){
|
||||
printk("Read of %d bytes from '%s' failed, err = %d\n", size,
|
||||
filename, -n);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
os_close_file(fd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
|
@ -57,6 +57,7 @@ EXPORT_SYMBOL(copy_to_user_tt);
|
|||
EXPORT_SYMBOL(strncpy_from_user_skas);
|
||||
EXPORT_SYMBOL(copy_to_user_skas);
|
||||
EXPORT_SYMBOL(copy_from_user_skas);
|
||||
EXPORT_SYMBOL(clear_user_skas);
|
||||
#endif
|
||||
EXPORT_SYMBOL(uml_strdup);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ static __init void do_uml_initcalls(void)
|
|||
|
||||
static void last_ditch_exit(int sig)
|
||||
{
|
||||
CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
|
||||
kmalloc_ok = 0;
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
signal(SIGHUP, SIG_DFL);
|
||||
|
@ -87,7 +87,7 @@ int main(int argc, char **argv, char **envp)
|
|||
{
|
||||
char **new_argv;
|
||||
sigset_t mask;
|
||||
int ret, i;
|
||||
int ret, i, err;
|
||||
|
||||
/* Enable all signals except SIGIO - in some environments, we can
|
||||
* enter with some signals blocked
|
||||
|
@ -160,27 +160,29 @@ int main(int argc, char **argv, char **envp)
|
|||
*/
|
||||
change_sig(SIGPROF, 0);
|
||||
|
||||
/* This signal stuff used to be in the reboot case. However,
|
||||
* sometimes a SIGVTALRM can come in when we're halting (reproducably
|
||||
* when writing out gcov information, presumably because that takes
|
||||
* some time) and cause a segfault.
|
||||
*/
|
||||
|
||||
/* stop timers and set SIG*ALRM to be ignored */
|
||||
disable_timer();
|
||||
|
||||
/* disable SIGIO for the fds and set SIGIO to be ignored */
|
||||
err = deactivate_all_fds();
|
||||
if(err)
|
||||
printf("deactivate_all_fds failed, errno = %d\n", -err);
|
||||
|
||||
/* Let any pending signals fire now. This ensures
|
||||
* that they won't be delivered after the exec, when
|
||||
* they are definitely not expected.
|
||||
*/
|
||||
unblock_signals();
|
||||
|
||||
/* Reboot */
|
||||
if(ret){
|
||||
int err;
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* stop timers and set SIG*ALRM to be ignored */
|
||||
disable_timer();
|
||||
|
||||
/* disable SIGIO for the fds and set SIGIO to be ignored */
|
||||
err = deactivate_all_fds();
|
||||
if(err)
|
||||
printf("deactivate_all_fds failed, errno = %d\n",
|
||||
-err);
|
||||
|
||||
/* Let any pending signals fire now. This ensures
|
||||
* that they won't be delivered after the exec, when
|
||||
* they are definitely not expected.
|
||||
*/
|
||||
unblock_signals();
|
||||
|
||||
execvp(new_argv[0], new_argv);
|
||||
perror("Failed to exec kernel");
|
||||
ret = 1;
|
||||
|
|
|
@ -100,12 +100,37 @@ void mem_init(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a page table and place a pointer to it in a middle page
|
||||
* directory entry.
|
||||
*/
|
||||
static void __init one_page_table_init(pmd_t *pmd)
|
||||
{
|
||||
if (pmd_none(*pmd)) {
|
||||
pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
set_pmd(pmd, __pmd(_KERNPG_TABLE +
|
||||
(unsigned long) __pa(pte)));
|
||||
if (pte != pte_offset_kernel(pmd, 0))
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static void __init one_md_table_init(pud_t *pud)
|
||||
{
|
||||
#ifdef CONFIG_3_LEVEL_PGTABLES
|
||||
pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table)));
|
||||
if (pmd_table != pmd_offset(pud, 0))
|
||||
BUG();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init fixrange_init(unsigned long start, unsigned long end,
|
||||
pgd_t *pgd_base)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
int i, j;
|
||||
unsigned long vaddr;
|
||||
|
||||
|
@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
|
|||
pgd = pgd_base + i;
|
||||
|
||||
for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
|
||||
pmd = (pmd_t *)pgd;
|
||||
pud = pud_offset(pgd, vaddr);
|
||||
if (pud_none(*pud))
|
||||
one_md_table_init(pud);
|
||||
pmd = pmd_offset(pud, vaddr);
|
||||
for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
set_pmd(pmd, __pmd(_KERNPG_TABLE +
|
||||
(unsigned long) __pa(pte)));
|
||||
if (pte != pte_offset_kernel(pmd, 0))
|
||||
BUG();
|
||||
}
|
||||
one_page_table_init(pmd);
|
||||
vaddr += PMD_SIZE;
|
||||
}
|
||||
j = 0;
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "tlb.h"
|
||||
#include "frame_kern.h"
|
||||
#include "sigcontext.h"
|
||||
#include "2_5compat.h"
|
||||
#include "os.h"
|
||||
#include "mode.h"
|
||||
#include "mode_kern.h"
|
||||
|
@ -55,18 +54,6 @@
|
|||
*/
|
||||
struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
|
||||
|
||||
struct task_struct *get_task(int pid, int require)
|
||||
{
|
||||
struct task_struct *ret;
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
ret = find_task_by_pid(pid);
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int external_pid(void *t)
|
||||
{
|
||||
struct task_struct *task = t ? t : current;
|
||||
|
@ -189,7 +176,6 @@ void default_idle(void)
|
|||
|
||||
while(1){
|
||||
/* endless idle loop with no priority at all */
|
||||
SET_PRI(current);
|
||||
|
||||
/*
|
||||
* although we are an idle CPU, we do not want to
|
||||
|
@ -212,11 +198,6 @@ int page_size(void)
|
|||
return(PAGE_SIZE);
|
||||
}
|
||||
|
||||
unsigned long page_mask(void)
|
||||
{
|
||||
return(PAGE_MASK);
|
||||
}
|
||||
|
||||
void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
|
||||
pte_t *pte_out)
|
||||
{
|
||||
|
@ -349,11 +330,6 @@ char *uml_strdup(char *string)
|
|||
return(new);
|
||||
}
|
||||
|
||||
void *get_init_task(void)
|
||||
{
|
||||
return(&init_thread_union.thread_info.task);
|
||||
}
|
||||
|
||||
int copy_to_user_proc(void __user *to, void *from, int size)
|
||||
{
|
||||
return(copy_to_user(to, from, size));
|
||||
|
@ -480,15 +456,3 @@ unsigned long arch_align_stack(unsigned long sp)
|
|||
return sp & ~0xf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
|
|
|
@ -28,9 +28,9 @@ static inline void set_singlestepping(struct task_struct *child, int on)
|
|||
child->thread.singlestep_syscall = 0;
|
||||
|
||||
#ifdef SUBARCH_SET_SINGLESTEPPING
|
||||
SUBARCH_SET_SINGLESTEPPING(child, on)
|
||||
SUBARCH_SET_SINGLESTEPPING(child, on);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by kernel/ptrace.c when detaching..
|
||||
|
@ -83,7 +83,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
|
|||
}
|
||||
|
||||
#ifdef SUBACH_PTRACE_SPECIAL
|
||||
SUBARCH_PTRACE_SPECIAL(child,request,addr,data)
|
||||
SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
|
||||
#endif
|
||||
|
||||
ret = ptrace_check_attach(child, request == PTRACE_KILL);
|
||||
|
@ -322,11 +322,9 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
|
|||
UPT_SYSCALL_ARG2(regs),
|
||||
UPT_SYSCALL_ARG3(regs),
|
||||
UPT_SYSCALL_ARG4(regs));
|
||||
else {
|
||||
int res = UPT_SYSCALL_RET(regs);
|
||||
audit_syscall_exit(current, AUDITSC_RESULT(res),
|
||||
res);
|
||||
}
|
||||
else audit_syscall_exit(current,
|
||||
AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
|
||||
UPT_SYSCALL_RET(regs));
|
||||
}
|
||||
|
||||
/* Fake a debug trap */
|
||||
|
@ -356,14 +354,3 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
|
|||
current->exit_code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/config.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/kernel.h"
|
||||
#include "linux/module.h"
|
||||
|
@ -12,14 +13,14 @@
|
|||
#include "sysrq.h"
|
||||
#include "user_util.h"
|
||||
|
||||
void show_trace(unsigned long * stack)
|
||||
/* Catch non-i386 SUBARCH's. */
|
||||
#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
|
||||
void show_trace(struct task_struct *task, unsigned long * stack)
|
||||
{
|
||||
/* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from
|
||||
* arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/
|
||||
unsigned long addr;
|
||||
|
||||
if (!stack) {
|
||||
stack = (unsigned long*) &stack;
|
||||
stack = (unsigned long*) &stack;
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,7 @@ void show_trace(unsigned long * stack)
|
|||
}
|
||||
printk("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* stack dumps generator - this is used by arch-independent code.
|
||||
|
@ -44,7 +46,7 @@ void dump_stack(void)
|
|||
{
|
||||
unsigned long stack;
|
||||
|
||||
show_trace(&stack);
|
||||
show_trace(current, &stack);
|
||||
}
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
|
||||
|
@ -59,7 +61,11 @@ void show_stack(struct task_struct *task, unsigned long *esp)
|
|||
int i;
|
||||
|
||||
if (esp == NULL) {
|
||||
if (task != current) {
|
||||
if (task != current && task != NULL) {
|
||||
/* XXX: Isn't this bogus? I.e. isn't this the
|
||||
* *userspace* stack of this task? If not so, use this
|
||||
* even when task == current (as in i386).
|
||||
*/
|
||||
esp = (unsigned long *) KSTK_ESP(task);
|
||||
/* Which one? No actual difference - just coding style.*/
|
||||
//esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
|
||||
|
@ -77,5 +83,6 @@ void show_stack(struct task_struct *task, unsigned long *esp)
|
|||
printk("%08lx ", *stack++);
|
||||
}
|
||||
|
||||
show_trace(esp);
|
||||
printk("Call Trace: \n");
|
||||
show_trace(current, esp);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "kern.h"
|
||||
#include "chan_kern.h"
|
||||
#include "mconsole_kern.h"
|
||||
#include "2_5compat.h"
|
||||
#include "mem.h"
|
||||
#include "mem_kern.h"
|
||||
|
||||
|
@ -57,10 +56,11 @@ int handle_page_fault(unsigned long address, unsigned long ip,
|
|||
*code_out = SEGV_ACCERR;
|
||||
if(is_write && !(vma->vm_flags & VM_WRITE))
|
||||
goto out;
|
||||
|
||||
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
|
||||
goto out;
|
||||
|
||||
page = address & PAGE_MASK;
|
||||
pgd = pgd_offset(mm, page);
|
||||
pud = pud_offset(pgd, page);
|
||||
pmd = pmd_offset(pud, page);
|
||||
do {
|
||||
survive:
|
||||
switch (handle_mm_fault(mm, vma, address, is_write)){
|
||||
|
@ -106,33 +106,6 @@ int handle_page_fault(unsigned long address, unsigned long ip,
|
|||
goto out;
|
||||
}
|
||||
|
||||
LIST_HEAD(physmem_remappers);
|
||||
|
||||
void register_remapper(struct remapper *info)
|
||||
{
|
||||
list_add(&info->list, &physmem_remappers);
|
||||
}
|
||||
|
||||
static int check_remapped_addr(unsigned long address, int is_write)
|
||||
{
|
||||
struct remapper *remapper;
|
||||
struct list_head *ele;
|
||||
__u64 offset;
|
||||
int fd;
|
||||
|
||||
fd = phys_mapping(__pa(address), &offset);
|
||||
if(fd == -1)
|
||||
return(0);
|
||||
|
||||
list_for_each(ele, &physmem_remappers){
|
||||
remapper = list_entry(ele, struct remapper, list);
|
||||
if((*remapper->proc)(fd, address, is_write, offset))
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We give a *copy* of the faultinfo in the regs to segv.
|
||||
* This must be done, since nesting SEGVs could overwrite
|
||||
|
@ -151,8 +124,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
|
|||
flush_tlb_kernel_vm();
|
||||
return(0);
|
||||
}
|
||||
else if(check_remapped_addr(address & PAGE_MASK, is_write))
|
||||
return(0);
|
||||
else if(current->mm == NULL)
|
||||
panic("Segfault with no mm");
|
||||
err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
|
||||
|
|
|
@ -12,6 +12,7 @@ EXPORT_SYMBOL(__do_copy_to_user);
|
|||
EXPORT_SYMBOL(__do_strncpy_from_user);
|
||||
EXPORT_SYMBOL(__do_strnlen_user);
|
||||
EXPORT_SYMBOL(__do_clear_user);
|
||||
EXPORT_SYMBOL(clear_user_tt);
|
||||
|
||||
EXPORT_SYMBOL(tracing_pid);
|
||||
EXPORT_SYMBOL(honeypot);
|
||||
|
|
|
@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last)
|
|||
unsigned long flags;
|
||||
int err, vtalrm, alrm, prof, cpu;
|
||||
char c;
|
||||
/* jailing and SMP are incompatible, so this doesn't need to be
|
||||
* made per-cpu
|
||||
*/
|
||||
static int reading;
|
||||
|
||||
from = prev;
|
||||
to = next;
|
||||
|
@ -59,13 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last)
|
|||
c = 0;
|
||||
set_current(to);
|
||||
|
||||
reading = 0;
|
||||
err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
|
||||
if(err != sizeof(c))
|
||||
panic("write of switch_pipe failed, err = %d", -err);
|
||||
|
||||
reading = 1;
|
||||
if(from->thread.mode.tt.switch_pipe[0] == -1)
|
||||
if(from->thread.mode.tt.switch_pipe[0] == -1)
|
||||
os_kill_process(os_getpid(), 0);
|
||||
|
||||
err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
|
||||
|
|
|
@ -111,12 +111,6 @@ struct seq_operations cpuinfo_op = {
|
|||
.show = show_cpuinfo,
|
||||
};
|
||||
|
||||
pte_t * __bad_pagetable(void)
|
||||
{
|
||||
panic("Someone should implement __bad_pagetable");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Set in linux_main */
|
||||
unsigned long host_task_size;
|
||||
unsigned long task_size;
|
||||
|
|
|
@ -73,6 +73,8 @@ SECTIONS
|
|||
|
||||
.got : { *(.got.plt) *(.got) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
/* We want the small data sections together, so single-instruction offsets
|
||||
can access them all, and initialized data all before uninitialized, so
|
||||
we can shorten the on-disk segment size. */
|
||||
|
|
|
@ -9,11 +9,11 @@ USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
|
|||
|
||||
SYMLINKS = bitops.c semaphore.c highmem.c module.c
|
||||
|
||||
include arch/um/scripts/Makefile.rules
|
||||
|
||||
bitops.c-dir = lib
|
||||
semaphore.c-dir = kernel
|
||||
highmem.c-dir = mm
|
||||
module.c-dir = kernel
|
||||
|
||||
subdir- := util
|
||||
|
||||
include arch/um/scripts/Makefile.rules
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "linux/delay.h"
|
||||
#include "asm/param.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/param.h>
|
||||
|
||||
void __delay(unsigned long time)
|
||||
{
|
||||
|
@ -20,13 +22,19 @@ void __udelay(unsigned long usecs)
|
|||
int i, n;
|
||||
|
||||
n = (loops_per_jiffy * HZ * usecs) / MILLION;
|
||||
for(i=0;i<n;i++) ;
|
||||
for(i=0;i<n;i++)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__udelay);
|
||||
|
||||
void __const_udelay(unsigned long usecs)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
n = (loops_per_jiffy * HZ * usecs) / MILLION;
|
||||
for(i=0;i<n;i++) ;
|
||||
for(i=0;i<n;i++)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__const_udelay);
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/config.h"
|
||||
#include "linux/kernel.h"
|
||||
#include "linux/smp.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/kallsyms.h"
|
||||
#include "asm/ptrace.h"
|
||||
#include "sysrq.h"
|
||||
|
||||
/* This is declared by <linux/sched.h> */
|
||||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
printk("\n");
|
||||
|
@ -31,5 +34,80 @@ void show_regs(struct pt_regs *regs)
|
|||
0xffff & PT_REGS_DS(regs),
|
||||
0xffff & PT_REGS_ES(regs));
|
||||
|
||||
show_trace((unsigned long *) ®s);
|
||||
show_trace(NULL, (unsigned long *) ®s);
|
||||
}
|
||||
|
||||
/* Copied from i386. */
|
||||
static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
|
||||
{
|
||||
return p > (void *)tinfo &&
|
||||
p < (void *)tinfo + THREAD_SIZE - 3;
|
||||
}
|
||||
|
||||
/* Adapted from i386 (we also print the address we read from). */
|
||||
static inline unsigned long print_context_stack(struct thread_info *tinfo,
|
||||
unsigned long *stack, unsigned long ebp)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
while (valid_stack_ptr(tinfo, (void *)ebp)) {
|
||||
addr = *(unsigned long *)(ebp + 4);
|
||||
printk("%08lx: [<%08lx>]", ebp + 4, addr);
|
||||
print_symbol(" %s", addr);
|
||||
printk("\n");
|
||||
ebp = *(unsigned long *)ebp;
|
||||
}
|
||||
#else
|
||||
while (valid_stack_ptr(tinfo, stack)) {
|
||||
addr = *stack;
|
||||
if (__kernel_text_address(addr)) {
|
||||
printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
|
||||
print_symbol(" %s", addr);
|
||||
printk("\n");
|
||||
}
|
||||
stack++;
|
||||
}
|
||||
#endif
|
||||
return ebp;
|
||||
}
|
||||
|
||||
void show_trace(struct task_struct* task, unsigned long * stack)
|
||||
{
|
||||
unsigned long ebp;
|
||||
struct thread_info *context;
|
||||
|
||||
/* Turn this into BUG_ON if possible. */
|
||||
if (!stack) {
|
||||
stack = (unsigned long*) &stack;
|
||||
printk("show_trace: got NULL stack, implicit assumption task == current");
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
if (!task)
|
||||
task = current;
|
||||
|
||||
if (task != current) {
|
||||
//ebp = (unsigned long) KSTK_EBP(task);
|
||||
/* Which one? No actual difference - just coding style.*/
|
||||
ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
|
||||
} else {
|
||||
asm ("movl %%ebp, %0" : "=r" (ebp) : );
|
||||
}
|
||||
|
||||
context = (struct thread_info *)
|
||||
((unsigned long)stack & (~(THREAD_SIZE - 1)));
|
||||
print_context_stack(context, stack, ebp);
|
||||
|
||||
/*while (((long) stack & (THREAD_SIZE-1)) != 0) {
|
||||
addr = *stack;
|
||||
if (__kernel_text_address(addr)) {
|
||||
printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
|
||||
print_symbol(" %s", addr);
|
||||
printk("\n");
|
||||
}
|
||||
stack++;
|
||||
}*/
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -27,17 +27,5 @@ void show_regs(struct pt_regs_subarch *regs)
|
|||
0xffff & regs->xds, 0xffff & regs->xes);
|
||||
#endif
|
||||
|
||||
show_trace(®s->gpr[1]);
|
||||
show_trace(current, ®s->gpr[1]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
|
|
|
@ -14,11 +14,11 @@ obj-$(CONFIG_MODULES) += module.o um_module.o
|
|||
|
||||
USER_OBJS := ptrace_user.o sigcontext.o
|
||||
|
||||
include arch/um/scripts/Makefile.rules
|
||||
|
||||
SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
|
||||
semaphore.c thunk.S module.c
|
||||
|
||||
include arch/um/scripts/Makefile.rules
|
||||
|
||||
bitops.c-dir = lib
|
||||
csum-copy.S-dir = lib
|
||||
csum-partial.c-dir = lib
|
||||
|
@ -28,6 +28,4 @@ semaphore.c-dir = kernel
|
|||
thunk.S-dir = lib
|
||||
module.c-dir = kernel
|
||||
|
||||
CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
|
||||
|
||||
subdir- := util
|
||||
|
|
|
@ -5,40 +5,37 @@
|
|||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include "linux/delay.h"
|
||||
#include "asm/processor.h"
|
||||
#include "asm/param.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/param.h>
|
||||
|
||||
void __delay(unsigned long loops)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for(i = 0; i < loops; i++) ;
|
||||
for(i = 0; i < loops; i++)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usecs)
|
||||
{
|
||||
int i, n;
|
||||
unsigned long i, n;
|
||||
|
||||
n = (loops_per_jiffy * HZ * usecs) / MILLION;
|
||||
for(i=0;i<n;i++) ;
|
||||
for(i=0;i<n;i++)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__udelay);
|
||||
|
||||
void __const_udelay(unsigned long usecs)
|
||||
{
|
||||
int i, n;
|
||||
unsigned long i, n;
|
||||
|
||||
n = (loops_per_jiffy * HZ * usecs) / MILLION;
|
||||
for(i=0;i<n;i++) ;
|
||||
for(i=0;i<n;i++)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
EXPORT_SYMBOL(__const_udelay);
|
||||
|
|
|
@ -16,5 +16,4 @@ EXPORT_SYMBOL(__up_wakeup);
|
|||
EXPORT_SYMBOL(__memcpy);
|
||||
|
||||
/* Networking helper routines. */
|
||||
/*EXPORT_SYMBOL(csum_partial_copy_from);
|
||||
EXPORT_SYMBOL(csum_partial_copy_to);*/
|
||||
EXPORT_SYMBOL(ip_compute_csum);
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
*/
|
||||
|
||||
#define __FRAME_OFFSETS
|
||||
#include "asm/ptrace.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/errno.h"
|
||||
#include "asm/elf.h"
|
||||
#include <asm/ptrace.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/elf.h>
|
||||
|
||||
/* XXX x86_64 */
|
||||
unsigned long not_ss;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "asm/unistd.h"
|
||||
#include "asm/prctl.h" /* XXX This should get the constants from libc */
|
||||
#include "choose-mode.h"
|
||||
#include "kern.h"
|
||||
|
||||
asmlinkage long sys_uname64(struct new_utsname __user * name)
|
||||
{
|
||||
|
@ -132,23 +133,27 @@ static long arch_prctl_tt(int code, unsigned long addr)
|
|||
|
||||
#ifdef CONFIG_MODE_SKAS
|
||||
|
||||
/* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */
|
||||
static long arch_prctl_skas(int code, unsigned long addr)
|
||||
{
|
||||
long ret = 0;
|
||||
|
||||
switch(code){
|
||||
case ARCH_SET_GS:
|
||||
current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
|
||||
break;
|
||||
case ARCH_SET_FS:
|
||||
current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
|
||||
break;
|
||||
case ARCH_SET_GS:
|
||||
current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
|
||||
break;
|
||||
case ARCH_GET_FS:
|
||||
ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr);
|
||||
ret = put_user(current->thread.regs.regs.skas.
|
||||
regs[FS_BASE / sizeof(unsigned long)],
|
||||
(unsigned long __user *)addr);
|
||||
break;
|
||||
case ARCH_GET_GS:
|
||||
ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \
|
||||
long)], &addr);
|
||||
ret = put_user(current->thread.regs.regs.skas.
|
||||
regs[GS_BASE / sizeof(unsigned long)],
|
||||
(unsigned long __user *)addr);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
|
|
@ -36,14 +36,5 @@ void __show_regs(struct pt_regs * regs)
|
|||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
__show_regs(regs);
|
||||
show_trace((unsigned long *) ®s);
|
||||
show_trace(current, (unsigned long *) ®s);
|
||||
}
|
||||
|
||||
/* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue