Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02b2318e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6

* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: (26 commits)
  [SPARC64]: Fix UP build.
  [SPARC64]: dr-cpu unconfigure support.
  [SERIAL]: Fix console write locking in sparc drivers.
  [SPARC64]: Give more accurate errors in dr_cpu_configure().
  [SPARC64]: Clear cpu_{core,sibling}_map[] in smp_fill_in_sib_core_maps()
  [SPARC64]: Fix leak when DR added cpu does not bootup.
  [SPARC64]: Add ->set_affinity IRQ handlers.
  [SPARC64]: Process dr-cpu events in a kthread instead of workqueue.
  [SPARC64]: More sensible udelay implementation.
  [SPARC64]: SMP build fixes.
  [SPARC64]: mdesc.c needs linux/mm.h
  [SPARC64]: Fix build regressions added by dr-cpu changes.
  [SPARC64]: Unconditionally register vio_bus_type.
  [SPARC64]: Initial LDOM cpu hotplug support.
  [SPARC64]: Fix setting of variables in LDOM guest.
  [SPARC64]: Fix MD property lifetime bugs.
  [SPARC64]: Abstract out mdesc accesses for better MD update handling.
  [SPARC64]: Use more mearningful names for IRQ registry.
  [SPARC64]: Initial domain-services driver.
  [SPARC64]: Export powerd facilities for external entities.
  ...
parents b91cba52 d54bc279
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -108,6 +108,15 @@ config SECCOMP

source kernel/Kconfig.hz

config HOTPLUG_CPU
	bool "Support for hot-pluggable CPUs"
	depends on SMP
	select HOTPLUG
	---help---
	  Say Y here to experiment with turning CPUs off and on.  CPUs
	  can be controlled through /sys/devices/system/cpu/cpu#.
	  Say N if you want to disable CPU hotplug.

source "init/Kconfig"

config SYSVIPC_COMPAT
@@ -305,6 +314,12 @@ config SUN_IO
	bool
	default y

config SUN_LDOMS
	bool "Sun Logical Domains support"
	help
	  Say Y here is you want to support virtual devices via
	  Logical Domains.

config PCI
	bool "PCI support"
	select ARCH_SUPPORTS_MSI
+2 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PCI)	 += ebus.o isa.o pci_common.o pci_iommu.o \
			    pci_psycho.o pci_sabre.o pci_schizo.o \
			    pci_sun4v.o pci_sun4v_asm.o pci_fire.o
obj-$(CONFIG_SMP)	 += smp.o trampoline.o
obj-$(CONFIG_SMP)	 += smp.o trampoline.o hvtramp.o
obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
@@ -26,6 +26,7 @@ obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
obj-$(CONFIG_AUDIT) += audit.o
obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o
obj-y += $(obj-yy)
+1158 −0

File added.

Preview size limit exceeded, changes collapsed.

+139 −0
Original line number Diff line number Diff line
/* hvtramp.S: Hypervisor start-cpu trampoline code.
 *
 * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
 */

#include <asm/thread_info.h>
#include <asm/hypervisor.h>
#include <asm/scratchpad.h>
#include <asm/spitfire.h>
#include <asm/hvtramp.h>
#include <asm/pstate.h>
#include <asm/ptrace.h>
#include <asm/asi.h>

	.text
	.align		8
	.globl		hv_cpu_startup, hv_cpu_startup_end

	/* This code executes directly out of the hypervisor
	 * with physical addressing (va==pa).  %o0 contains
	 * our client argument which for Linux points to
	 * a descriptor data structure which defines the
	 * MMU entries we need to load up.
	 *
	 * After we set things up we enable the MMU and call
	 * into the kernel.
	 *
	 * First setup basic privileged cpu state.
	 */
hv_cpu_startup:
	wrpr		%g0, 0, %gl
	wrpr		%g0, 15, %pil
	wrpr		%g0, 0, %canrestore
	wrpr		%g0, 0, %otherwin
	wrpr		%g0, 6, %cansave
	wrpr		%g0, 6, %cleanwin
	wrpr		%g0, 0, %cwp
	wrpr		%g0, 0, %wstate
	wrpr		%g0, 0, %tl

	sethi		%hi(sparc64_ttable_tl0), %g1
	wrpr		%g1, %tba

	mov		%o0, %l0

	lduw		[%l0 + HVTRAMP_DESCR_CPU], %g1
	mov		SCRATCHPAD_CPUID, %g2
	stxa		%g1, [%g2] ASI_SCRATCHPAD

	ldx		[%l0 + HVTRAMP_DESCR_FAULT_INFO_VA], %g2
	stxa		%g2, [%g0] ASI_SCRATCHPAD

	mov		0, %l1
	lduw		[%l0 + HVTRAMP_DESCR_NUM_MAPPINGS], %l2
	add		%l0, HVTRAMP_DESCR_MAPS, %l3

1:	ldx		[%l3 + HVTRAMP_MAPPING_VADDR], %o0
	clr		%o1
	ldx		[%l3 + HVTRAMP_MAPPING_TTE], %o2
	mov		HV_MMU_IMMU | HV_MMU_DMMU, %o3
	mov		HV_FAST_MMU_MAP_PERM_ADDR, %o5
	ta		HV_FAST_TRAP

	brnz,pn		%o0, 80f
	 nop

	add		%l1, 1, %l1
	cmp		%l1, %l2
	blt,a,pt	%xcc, 1b
	 add		%l3, HVTRAMP_MAPPING_SIZE, %l3

	ldx		[%l0 + HVTRAMP_DESCR_FAULT_INFO_PA], %o0
	mov		HV_FAST_MMU_FAULT_AREA_CONF, %o5
	ta		HV_FAST_TRAP

	brnz,pn		%o0, 80f
	 nop

	wrpr		%g0, (PSTATE_PRIV | PSTATE_PEF), %pstate

	ldx		[%l0 + HVTRAMP_DESCR_THREAD_REG], %l6

	mov		1, %o0
	set		1f, %o1
	mov		HV_FAST_MMU_ENABLE, %o5
	ta		HV_FAST_TRAP

	ba,pt		%xcc, 80f
	 nop

1:
	wr		%g0, 0, %fprs
	wr		%g0, ASI_P, %asi

	mov		PRIMARY_CONTEXT, %g7
	stxa		%g0, [%g7] ASI_MMU
	membar		#Sync

	mov		SECONDARY_CONTEXT, %g7
	stxa		%g0, [%g7] ASI_MMU
	membar		#Sync

	mov		%l6, %g6
	ldx		[%g6 + TI_TASK], %g4

	mov		1, %g5
	sllx		%g5, THREAD_SHIFT, %g5
	sub		%g5, (STACKFRAME_SZ + STACK_BIAS), %g5
	add		%g6, %g5, %sp
	mov		0, %fp

	call		init_irqwork_curcpu
	 nop
	call		hard_smp_processor_id
	 nop

	mov		%o0, %o1
	mov		0, %o0
	mov		0, %o2
	call		sun4v_init_mondo_queues
	 mov		1, %o3

	call		init_cur_cpu_trap
	 mov		%g6, %o0

	wrpr		%g0, (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE), %pstate

	call		smp_callin
	 nop
	call		cpu_idle
	 mov		0, %o0
	call		cpu_panic
	 nop

80:	ba,pt		%xcc, 80b
	 nop

	.align		8
hv_cpu_startup_end:
+84 −0
Original line number Diff line number Diff line
@@ -293,6 +293,11 @@ static void sun4u_irq_enable(unsigned int virt_irq)
	}
}

static void sun4u_set_affinity(unsigned int virt_irq, cpumask_t mask)
{
	sun4u_irq_enable(virt_irq);
}

static void sun4u_irq_disable(unsigned int virt_irq)
{
	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
@@ -309,6 +314,10 @@ static void sun4u_irq_disable(unsigned int virt_irq)
static void sun4u_irq_end(unsigned int virt_irq)
{
	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
	struct irq_desc *desc = irq_desc + virt_irq;

	if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
		return;

	if (likely(data))
		upa_writeq(ICLR_IDLE, data->iclr);
@@ -340,6 +349,24 @@ static void sun4v_irq_enable(unsigned int virt_irq)
	}
}

static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
	unsigned int ino = bucket - &ivector_table[0];

	if (likely(bucket)) {
		unsigned long cpuid;
		int err;

		cpuid = irq_choose_cpu(virt_irq);

		err = sun4v_intr_settarget(ino, cpuid);
		if (err != HV_EOK)
			printk("sun4v_intr_settarget(%x,%lu): err(%d)\n",
			       ino, cpuid, err);
	}
}

static void sun4v_irq_disable(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
@@ -373,6 +400,10 @@ static void sun4v_irq_end(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
	unsigned int ino = bucket - &ivector_table[0];
	struct irq_desc *desc = irq_desc + virt_irq;

	if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
		return;

	if (likely(bucket)) {
		int err;
@@ -418,6 +449,28 @@ static void sun4v_virq_enable(unsigned int virt_irq)
	}
}

static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
	unsigned int ino = bucket - &ivector_table[0];

	if (likely(bucket)) {
		unsigned long cpuid, dev_handle, dev_ino;
		int err;

		cpuid = irq_choose_cpu(virt_irq);

		dev_handle = ino & IMAP_IGN;
		dev_ino = ino & IMAP_INO;

		err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
		if (err != HV_EOK)
			printk("sun4v_vintr_set_target(%lx,%lx,%lu): "
			       "err(%d)\n",
			       dev_handle, dev_ino, cpuid, err);
	}
}

static void sun4v_virq_disable(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
@@ -443,6 +496,10 @@ static void sun4v_virq_end(unsigned int virt_irq)
{
	struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
	unsigned int ino = bucket - &ivector_table[0];
	struct irq_desc *desc = irq_desc + virt_irq;

	if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
		return;

	if (likely(bucket)) {
		unsigned long dev_handle, dev_ino;
@@ -477,6 +534,7 @@ static struct irq_chip sun4u_irq = {
	.enable		= sun4u_irq_enable,
	.disable	= sun4u_irq_disable,
	.end		= sun4u_irq_end,
	.set_affinity	= sun4u_set_affinity,
};

static struct irq_chip sun4u_irq_ack = {
@@ -485,6 +543,7 @@ static struct irq_chip sun4u_irq_ack = {
	.disable	= sun4u_irq_disable,
	.ack		= run_pre_handler,
	.end		= sun4u_irq_end,
	.set_affinity	= sun4u_set_affinity,
};

static struct irq_chip sun4v_irq = {
@@ -492,6 +551,7 @@ static struct irq_chip sun4v_irq = {
	.enable		= sun4v_irq_enable,
	.disable	= sun4v_irq_disable,
	.end		= sun4v_irq_end,
	.set_affinity	= sun4v_set_affinity,
};

static struct irq_chip sun4v_irq_ack = {
@@ -500,6 +560,7 @@ static struct irq_chip sun4v_irq_ack = {
	.disable	= sun4v_irq_disable,
	.ack		= run_pre_handler,
	.end		= sun4v_irq_end,
	.set_affinity	= sun4v_set_affinity,
};

#ifdef CONFIG_PCI_MSI
@@ -511,6 +572,7 @@ static struct irq_chip sun4v_msi = {
	.disable	= sun4v_msi_disable,
	.ack		= run_pre_handler,
	.end		= sun4v_irq_end,
	.set_affinity	= sun4v_set_affinity,
};
#endif

@@ -519,6 +581,7 @@ static struct irq_chip sun4v_virq = {
	.enable		= sun4v_virq_enable,
	.disable	= sun4v_virq_disable,
	.end		= sun4v_virq_end,
	.set_affinity	= sun4v_virt_set_affinity,
};

static struct irq_chip sun4v_virq_ack = {
@@ -527,6 +590,7 @@ static struct irq_chip sun4v_virq_ack = {
	.disable	= sun4v_virq_disable,
	.ack		= run_pre_handler,
	.end		= sun4v_virq_end,
	.set_affinity	= sun4v_virt_set_affinity,
};

void irq_install_pre_handler(int virt_irq,
@@ -739,6 +803,26 @@ void handler_irq(int irq, struct pt_regs *regs)
	set_irq_regs(old_regs);
}

#ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(void)
{
	unsigned int irq;

	for (irq = 0; irq < NR_IRQS; irq++) {
		unsigned long flags;

		spin_lock_irqsave(&irq_desc[irq].lock, flags);
		if (irq_desc[irq].action &&
		    !(irq_desc[irq].status & IRQ_PER_CPU)) {
			if (irq_desc[irq].chip->set_affinity)
				irq_desc[irq].chip->set_affinity(irq,
					irq_desc[irq].affinity);
		}
		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
	}
}
#endif

struct sun5_timer {
	u64	count0;
	u64	limit0;
Loading