aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/defconfig26
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/entry.S94
-rw-r--r--arch/sparc64/kernel/hvapi.c189
-rw-r--r--arch/sparc64/kernel/of_device.c7
-rw-r--r--arch/sparc64/kernel/setup.c3
-rw-r--r--arch/sparc64/kernel/smp.c3
-rw-r--r--arch/sparc64/kernel/time.c2
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S4
9 files changed, 304 insertions, 26 deletions
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 585ef4fb7591..65840a62bb9c 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.21 3# Linux kernel version: 2.6.22-rc1
4# Fri May 11 14:31:45 2007 4# Mon May 14 04:17:48 2007
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -508,10 +508,6 @@ CONFIG_ISCSI_TCP=m
508# CONFIG_SCSI_ESP_CORE is not set 508# CONFIG_SCSI_ESP_CORE is not set
509# CONFIG_SCSI_SUNESP is not set 509# CONFIG_SCSI_SUNESP is not set
510# CONFIG_SCSI_SRP is not set 510# CONFIG_SCSI_SRP is not set
511
512#
513# Serial ATA (prod) and Parallel ATA (experimental) drivers
514#
515# CONFIG_ATA is not set 511# CONFIG_ATA is not set
516 512
517# 513#
@@ -568,10 +564,6 @@ CONFIG_DUMMY=m
568# ARCnet devices 564# ARCnet devices
569# 565#
570# CONFIG_ARCNET is not set 566# CONFIG_ARCNET is not set
571
572#
573# PHY device support
574#
575# CONFIG_PHYLIB is not set 567# CONFIG_PHYLIB is not set
576 568
577# 569#
@@ -611,10 +603,7 @@ CONFIG_NET_PCI=y
611# CONFIG_SUNDANCE is not set 603# CONFIG_SUNDANCE is not set
612# CONFIG_VIA_RHINE is not set 604# CONFIG_VIA_RHINE is not set
613# CONFIG_SC92031 is not set 605# CONFIG_SC92031 is not set
614 606CONFIG_NETDEV_1000=y
615#
616# Ethernet (1000 Mbit)
617#
618# CONFIG_ACENIC is not set 607# CONFIG_ACENIC is not set
619# CONFIG_DL2K is not set 608# CONFIG_DL2K is not set
620CONFIG_E1000=m 609CONFIG_E1000=m
@@ -634,10 +623,7 @@ CONFIG_TIGON3=m
634CONFIG_BNX2=m 623CONFIG_BNX2=m
635# CONFIG_QLA3XXX is not set 624# CONFIG_QLA3XXX is not set
636# CONFIG_ATL1 is not set 625# CONFIG_ATL1 is not set
637 626CONFIG_NETDEV_10000=y
638#
639# Ethernet (10000 Mbit)
640#
641# CONFIG_CHELSIO_T1 is not set 627# CONFIG_CHELSIO_T1 is not set
642# CONFIG_CHELSIO_T3 is not set 628# CONFIG_CHELSIO_T3 is not set
643# CONFIG_IXGB is not set 629# CONFIG_IXGB is not set
@@ -667,10 +653,6 @@ CONFIG_MLX4_DEBUG=y
667# CONFIG_USB_RTL8150 is not set 653# CONFIG_USB_RTL8150 is not set
668# CONFIG_USB_USBNET_MII is not set 654# CONFIG_USB_USBNET_MII is not set
669# CONFIG_USB_USBNET is not set 655# CONFIG_USB_USBNET is not set
670
671#
672# Wan interfaces
673#
674# CONFIG_WAN is not set 656# CONFIG_WAN is not set
675# CONFIG_FDDI is not set 657# CONFIG_FDDI is not set
676# CONFIG_HIPPI is not set 658# CONFIG_HIPPI is not set
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 6bf6fb65bc20..c749dccacc32 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -12,7 +12,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
12 irq.o ptrace.o time.o sys_sparc.o signal.o \ 12 irq.o ptrace.o time.o sys_sparc.o signal.o \
13 unaligned.o central.o pci.o starfire.o semaphore.o \ 13 unaligned.o central.o pci.o starfire.o semaphore.o \
14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ 14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
15 visemul.o prom.o of_device.o 15 visemul.o prom.o of_device.o hvapi.o
16 16
17obj-$(CONFIG_STACKTRACE) += stacktrace.o 17obj-$(CONFIG_STACKTRACE) += stacktrace.o
18obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ 18obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index c15a3edcb826..732b77cb71f8 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1843,3 +1843,97 @@ sun4v_cpu_state:
1843 mov %o1, %o0 1843 mov %o1, %o0
18441: retl 18441: retl
1845 nop 1845 nop
1846
1847 /* %o0: API group number
1848 * %o1: pointer to unsigned long major number storage
1849 * %o2: pointer to unsigned long minor number storage
1850 *
1851 * returns %o0: status
1852 */
1853 .globl sun4v_get_version
1854sun4v_get_version:
1855 mov HV_CORE_GET_VER, %o5
1856 mov %o1, %o3
1857 mov %o2, %o4
1858 ta HV_CORE_TRAP
1859 stx %o1, [%o3]
1860 retl
1861 stx %o2, [%o4]
1862
1863 /* %o0: API group number
1864 * %o1: desired major number
1865 * %o2: desired minor number
1866 * %o3: pointer to unsigned long actual minor number storage
1867 *
1868 * returns %o0: status
1869 */
1870 .globl sun4v_set_version
1871sun4v_set_version:
1872 mov HV_CORE_SET_VER, %o5
1873 mov %o3, %o4
1874 ta HV_CORE_TRAP
1875 retl
1876 stx %o1, [%o4]
1877
1878 /* %o0: pointer to unsigned long status
1879 *
1880 * returns %o0: signed character
1881 */
1882 .globl sun4v_con_getchar
1883sun4v_con_getchar:
1884 mov %o0, %o4
1885 mov HV_FAST_CONS_GETCHAR, %o5
1886 clr %o0
1887 clr %o1
1888 ta HV_FAST_TRAP
1889 stx %o0, [%o4]
1890 retl
1891 sra %o1, 0, %o0
1892
1893 /* %o0: signed long character
1894 *
1895 * returns %o0: status
1896 */
1897 .globl sun4v_con_putchar
1898sun4v_con_putchar:
1899 mov HV_FAST_CONS_PUTCHAR, %o5
1900 ta HV_FAST_TRAP
1901 retl
1902 sra %o0, 0, %o0
1903
1904 /* %o0: buffer real address
1905 * %o1: buffer size
1906 * %o2: pointer to unsigned long bytes_read
1907 *
1908 * returns %o0: status
1909 */
1910 .globl sun4v_con_read
1911sun4v_con_read:
1912 mov %o2, %o4
1913 mov HV_FAST_CONS_READ, %o5
1914 ta HV_FAST_TRAP
1915 brnz %o0, 1f
1916 cmp %o1, -1 /* break */
1917 be,a,pn %icc, 1f
1918 mov %o1, %o0
1919 cmp %o1, -2 /* hup */
1920 be,a,pn %icc, 1f
1921 mov %o1, %o0
1922 stx %o1, [%o4]
19231: retl
1924 nop
1925
1926 /* %o0: buffer real address
1927 * %o1: buffer size
1928 * %o2: pointer to unsigned long bytes_written
1929 *
1930 * returns %o0: status
1931 */
1932 .globl sun4v_con_write
1933sun4v_con_write:
1934 mov %o2, %o4
1935 mov HV_FAST_CONS_WRITE, %o5
1936 ta HV_FAST_TRAP
1937 stx %o1, [%o4]
1938 retl
1939 nop
diff --git a/arch/sparc64/kernel/hvapi.c b/arch/sparc64/kernel/hvapi.c
new file mode 100644
index 000000000000..f03ffc829c7a
--- /dev/null
+++ b/arch/sparc64/kernel/hvapi.c
@@ -0,0 +1,189 @@
1/* hvapi.c: Hypervisor API management.
2 *
3 * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
4 */
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/slab.h>
9
10#include <asm/hypervisor.h>
11#include <asm/oplib.h>
12
13/* If the hypervisor indicates that the API setting
14 * calls are unsupported, by returning HV_EBADTRAP or
15 * HV_ENOTSUPPORTED, we assume that API groups with the
16 * PRE_API flag set are major 1 minor 0.
17 */
18struct api_info {
19 unsigned long group;
20 unsigned long major;
21 unsigned long minor;
22 unsigned int refcnt;
23 unsigned int flags;
24#define FLAG_PRE_API 0x00000001
25};
26
27static struct api_info api_table[] = {
28 { .group = HV_GRP_SUN4V, .flags = FLAG_PRE_API },
29 { .group = HV_GRP_CORE, .flags = FLAG_PRE_API },
30 { .group = HV_GRP_INTR, },
31 { .group = HV_GRP_SOFT_STATE, },
32 { .group = HV_GRP_PCI, .flags = FLAG_PRE_API },
33 { .group = HV_GRP_LDOM, },
34 { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API },
35 { .group = HV_GRP_NCS, .flags = FLAG_PRE_API },
36 { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API },
37 { .group = HV_GRP_FIRE_PERF, },
38 { .group = HV_GRP_DIAG, .flags = FLAG_PRE_API },
39};
40
41static DEFINE_SPINLOCK(hvapi_lock);
42
43static struct api_info *__get_info(unsigned long group)
44{
45 int i;
46
47 for (i = 0; i < ARRAY_SIZE(api_table); i++) {
48 if (api_table[i].group == group)
49 return &api_table[i];
50 }
51 return NULL;
52}
53
54static void __get_ref(struct api_info *p)
55{
56 p->refcnt++;
57}
58
59static void __put_ref(struct api_info *p)
60{
61 if (--p->refcnt == 0) {
62 unsigned long ignore;
63
64 sun4v_set_version(p->group, 0, 0, &ignore);
65 p->major = p->minor = 0;
66 }
67}
68
69/* Register a hypervisor API specification. It indicates the
70 * API group and desired major+minor.
71 *
72 * If an existing API registration exists '0' (success) will
73 * be returned if it is compatible with the one being registered.
74 * Otherwise a negative error code will be returned.
75 *
76 * Otherwise an attempt will be made to negotiate the requested
77 * API group/major/minor with the hypervisor, and errors returned
78 * if that does not succeed.
79 */
80int sun4v_hvapi_register(unsigned long group, unsigned long major,
81 unsigned long *minor)
82{
83 struct api_info *p;
84 unsigned long flags;
85 int ret;
86
87 spin_lock_irqsave(&hvapi_lock, flags);
88 p = __get_info(group);
89 ret = -EINVAL;
90 if (p) {
91 if (p->refcnt) {
92 ret = -EINVAL;
93 if (p->major == major) {
94 *minor = p->minor;
95 ret = 0;
96 }
97 } else {
98 unsigned long actual_minor;
99 unsigned long hv_ret;
100
101 hv_ret = sun4v_set_version(group, major, *minor,
102 &actual_minor);
103 ret = -EINVAL;
104 if (hv_ret == HV_EOK) {
105 *minor = actual_minor;
106 p->major = major;
107 p->minor = actual_minor;
108 ret = 0;
109 } else if (hv_ret == HV_EBADTRAP ||
110 HV_ENOTSUPPORTED) {
111 if (p->flags & FLAG_PRE_API) {
112 if (major == 1) {
113 p->major = 1;
114 p->minor = 0;
115 *minor = 0;
116 ret = 0;
117 }
118 }
119 }
120 }
121
122 if (ret == 0)
123 __get_ref(p);
124 }
125 spin_unlock_irqrestore(&hvapi_lock, flags);
126
127 return ret;
128}
129EXPORT_SYMBOL(sun4v_hvapi_register);
130
131void sun4v_hvapi_unregister(unsigned long group)
132{
133 struct api_info *p;
134 unsigned long flags;
135
136 spin_lock_irqsave(&hvapi_lock, flags);
137 p = __get_info(group);
138 if (p)
139 __put_ref(p);
140 spin_unlock_irqrestore(&hvapi_lock, flags);
141}
142EXPORT_SYMBOL(sun4v_hvapi_unregister);
143
144int sun4v_hvapi_get(unsigned long group,
145 unsigned long *major,
146 unsigned long *minor)
147{
148 struct api_info *p;
149 unsigned long flags;
150 int ret;
151
152 spin_lock_irqsave(&hvapi_lock, flags);
153 ret = -EINVAL;
154 p = __get_info(group);
155 if (p && p->refcnt) {
156 *major = p->major;
157 *minor = p->minor;
158 ret = 0;
159 }
160 spin_unlock_irqrestore(&hvapi_lock, flags);
161
162 return ret;
163}
164EXPORT_SYMBOL(sun4v_hvapi_get);
165
166void __init sun4v_hvapi_init(void)
167{
168 unsigned long group, major, minor;
169
170 group = HV_GRP_SUN4V;
171 major = 1;
172 minor = 0;
173 if (sun4v_hvapi_register(group, major, &minor))
174 goto bad;
175
176 group = HV_GRP_CORE;
177 major = 1;
178 minor = 1;
179 if (sun4v_hvapi_register(group, major, &minor))
180 goto bad;
181
182 return;
183
184bad:
185 prom_printf("HVAPI: Cannot register API group "
186 "%lx with major(%u) minor(%u)\n",
187 group, major, minor);
188 prom_halt();
189}
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 7455f5d05519..16cc46a71872 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -537,6 +537,13 @@ static int __init build_one_resource(struct device_node *parent,
537 return 0; 537 return 0;
538 } 538 }
539 539
540 /* When we miss an I/O space match on PCI, just pass it up
541 * to the next PCI bridge and/or controller.
542 */
543 if (!strcmp(bus->name, "pci") &&
544 (addr[0] & 0x03000000) == 0x01000000)
545 return 0;
546
540 return 1; 547 return 1;
541} 548}
542 549
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 451028341c75..dea9c3c9ec5f 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -269,6 +269,7 @@ void __init per_cpu_patch(void)
269 269
270void __init sun4v_patch(void) 270void __init sun4v_patch(void)
271{ 271{
272 extern void sun4v_hvapi_init(void);
272 struct sun4v_1insn_patch_entry *p1; 273 struct sun4v_1insn_patch_entry *p1;
273 struct sun4v_2insn_patch_entry *p2; 274 struct sun4v_2insn_patch_entry *p2;
274 275
@@ -300,6 +301,8 @@ void __init sun4v_patch(void)
300 301
301 p2++; 302 p2++;
302 } 303 }
304
305 sun4v_hvapi_init();
303} 306}
304 307
305#ifdef CONFIG_SMP 308#ifdef CONFIG_SMP
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 8087d67a0cf8..24fdf1d0adc5 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -561,6 +561,9 @@ static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t
561 unsigned long flags, status; 561 unsigned long flags, status;
562 int cnt, retries, this_cpu, prev_sent, i; 562 int cnt, retries, this_cpu, prev_sent, i;
563 563
564 if (cpus_empty(mask))
565 return;
566
564 /* We have to do this whole thing with interrupts fully disabled. 567 /* We have to do this whole thing with interrupts fully disabled.
565 * Otherwise if we send an xcall from interrupt context it will 568 * Otherwise if we send an xcall from interrupt context it will
566 * corrupt both our mondo block and cpu list state. 569 * corrupt both our mondo block and cpu list state.
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 6b9a06e42542..2d63d7689962 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1030,7 +1030,7 @@ void __devinit setup_sparc64_timer(void)
1030 clockevents_register_device(sevt); 1030 clockevents_register_device(sevt);
1031} 1031}
1032 1032
1033#define SPARC64_NSEC_PER_CYC_SHIFT 32UL 1033#define SPARC64_NSEC_PER_CYC_SHIFT 10UL
1034 1034
1035static struct clocksource clocksource_tick = { 1035static struct clocksource clocksource_tick = {
1036 .rating = 100, 1036 .rating = 100,
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 13fa2a2e4513..fb648de18a8d 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -14,7 +14,7 @@ SECTIONS
14 .text 0x0000000000404000 : 14 .text 0x0000000000404000 :
15 { 15 {
16 _text = .; 16 _text = .;
17 *(.text) 17 TEXT_TEXT
18 SCHED_TEXT 18 SCHED_TEXT
19 LOCK_TEXT 19 LOCK_TEXT
20 KPROBES_TEXT 20 KPROBES_TEXT
@@ -27,7 +27,7 @@ SECTIONS
27 27
28 .data : 28 .data :
29 { 29 {
30 *(.data) 30 DATA_DATA
31 CONSTRUCTORS 31 CONSTRUCTORS
32 } 32 }
33 .data1 : { *(.data1) } 33 .data1 : { *(.data1) }