diff options
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/defconfig | 26 | ||||
-rw-r--r-- | arch/sparc64/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/entry.S | 94 | ||||
-rw-r--r-- | arch/sparc64/kernel/hvapi.c | 189 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 7 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/vmlinux.lds.S | 4 |
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 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_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 | 606 | CONFIG_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 |
620 | CONFIG_E1000=m | 609 | CONFIG_E1000=m |
@@ -634,10 +623,7 @@ CONFIG_TIGON3=m | |||
634 | CONFIG_BNX2=m | 623 | CONFIG_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 | 626 | CONFIG_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 | ||
17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
18 | obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ | 18 | obj-$(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 |
1844 | 1: retl | 1844 | 1: 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 | ||
1854 | sun4v_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 | ||
1871 | sun4v_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 | ||
1883 | sun4v_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 | ||
1898 | sun4v_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 | ||
1911 | sun4v_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] | ||
1923 | 1: 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 | ||
1933 | sun4v_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 | */ | ||
18 | struct 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 | |||
27 | static 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 | |||
41 | static DEFINE_SPINLOCK(hvapi_lock); | ||
42 | |||
43 | static 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 | |||
54 | static void __get_ref(struct api_info *p) | ||
55 | { | ||
56 | p->refcnt++; | ||
57 | } | ||
58 | |||
59 | static 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 | */ | ||
80 | int 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 | } | ||
129 | EXPORT_SYMBOL(sun4v_hvapi_register); | ||
130 | |||
131 | void 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 | } | ||
142 | EXPORT_SYMBOL(sun4v_hvapi_unregister); | ||
143 | |||
144 | int 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 | } | ||
164 | EXPORT_SYMBOL(sun4v_hvapi_get); | ||
165 | |||
166 | void __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 | |||
184 | bad: | ||
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 | ||
270 | void __init sun4v_patch(void) | 270 | void __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 | ||
1035 | static struct clocksource clocksource_tick = { | 1035 | static 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) } |