diff options
Diffstat (limited to 'arch/ppc64')
41 files changed, 508 insertions, 925 deletions
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index ef1f05e437c4..5cb343883e4d 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
| @@ -40,6 +40,10 @@ config COMPAT | |||
| 40 | bool | 40 | bool |
| 41 | default y | 41 | default y |
| 42 | 42 | ||
| 43 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
| 44 | bool | ||
| 45 | default y | ||
| 46 | |||
| 43 | # We optimistically allocate largepages from the VM, so make the limit | 47 | # We optimistically allocate largepages from the VM, so make the limit |
| 44 | # large enough (16MB). This badly named config option is actually | 48 | # large enough (16MB). This badly named config option is actually |
| 45 | # max order + 1 | 49 | # max order + 1 |
| @@ -258,6 +262,7 @@ config PPC_RTAS | |||
| 258 | config RTAS_PROC | 262 | config RTAS_PROC |
| 259 | bool "Proc interface to RTAS" | 263 | bool "Proc interface to RTAS" |
| 260 | depends on PPC_RTAS | 264 | depends on PPC_RTAS |
| 265 | default y | ||
| 261 | 266 | ||
| 262 | config RTAS_FLASH | 267 | config RTAS_FLASH |
| 263 | tristate "Firmware flash interface" | 268 | tristate "Firmware flash interface" |
| @@ -293,6 +298,9 @@ config SECCOMP | |||
| 293 | 298 | ||
| 294 | endmenu | 299 | endmenu |
| 295 | 300 | ||
| 301 | config ISA_DMA_API | ||
| 302 | bool | ||
| 303 | default y | ||
| 296 | 304 | ||
| 297 | menu "General setup" | 305 | menu "General setup" |
| 298 | 306 | ||
diff --git a/arch/ppc64/Kconfig.debug b/arch/ppc64/Kconfig.debug index e341a129da80..46b1ce58da3b 100644 --- a/arch/ppc64/Kconfig.debug +++ b/arch/ppc64/Kconfig.debug | |||
| @@ -5,6 +5,9 @@ source "lib/Kconfig.debug" | |||
| 5 | config DEBUG_STACKOVERFLOW | 5 | config DEBUG_STACKOVERFLOW |
| 6 | bool "Check for stack overflows" | 6 | bool "Check for stack overflows" |
| 7 | depends on DEBUG_KERNEL | 7 | depends on DEBUG_KERNEL |
| 8 | help | ||
| 9 | This option will cause messages to be printed if free stack space | ||
| 10 | drops below a certain limit. | ||
| 8 | 11 | ||
| 9 | config KPROBES | 12 | config KPROBES |
| 10 | bool "Kprobes" | 13 | bool "Kprobes" |
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index d33e20bcc52f..691f3008e698 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile | |||
| @@ -56,13 +56,20 @@ LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) | |||
| 56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ | 56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ |
| 57 | -mcall-aixdesc | 57 | -mcall-aixdesc |
| 58 | 58 | ||
| 59 | GCC_VERSION := $(call cc-version) | ||
| 60 | GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) | ||
| 61 | |||
| 59 | ifeq ($(CONFIG_POWER4_ONLY),y) | 62 | ifeq ($(CONFIG_POWER4_ONLY),y) |
| 60 | ifeq ($(CONFIG_ALTIVEC),y) | 63 | ifeq ($(CONFIG_ALTIVEC),y) |
| 64 | ifeq ($(GCC_BROKEN_VEC),y) | ||
| 61 | CFLAGS += $(call cc-option,-mcpu=970) | 65 | CFLAGS += $(call cc-option,-mcpu=970) |
| 62 | else | 66 | else |
| 63 | CFLAGS += $(call cc-option,-mcpu=power4) | 67 | CFLAGS += $(call cc-option,-mcpu=power4) |
| 64 | endif | 68 | endif |
| 65 | else | 69 | else |
| 70 | CFLAGS += $(call cc-option,-mcpu=power4) | ||
| 71 | endif | ||
| 72 | else | ||
| 66 | CFLAGS += $(call cc-option,-mtune=power4) | 73 | CFLAGS += $(call cc-option,-mtune=power4) |
| 67 | endif | 74 | endif |
| 68 | 75 | ||
diff --git a/arch/ppc64/boot/addnote.c b/arch/ppc64/boot/addnote.c index 66ff8103bf4d..719663a694bb 100644 --- a/arch/ppc64/boot/addnote.c +++ b/arch/ppc64/boot/addnote.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <unistd.h> | 19 | #include <unistd.h> |
| 20 | #include <string.h> | 20 | #include <string.h> |
| 21 | 21 | ||
| 22 | /* CHRP note section */ | ||
| 22 | char arch[] = "PowerPC"; | 23 | char arch[] = "PowerPC"; |
| 23 | 24 | ||
| 24 | #define N_DESCR 6 | 25 | #define N_DESCR 6 |
| @@ -31,6 +32,29 @@ unsigned int descr[N_DESCR] = { | |||
| 31 | 0x4000, /* load-base */ | 32 | 0x4000, /* load-base */ |
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 35 | /* RPA note section */ | ||
| 36 | char rpaname[] = "IBM,RPA-Client-Config"; | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Note: setting ignore_my_client_config *should* mean that OF ignores | ||
| 40 | * all the other fields, but there is a firmware bug which means that | ||
| 41 | * it looks at the splpar field at least. So these values need to be | ||
| 42 | * reasonable. | ||
| 43 | */ | ||
| 44 | #define N_RPA_DESCR 8 | ||
| 45 | unsigned int rpanote[N_RPA_DESCR] = { | ||
| 46 | 0, /* lparaffinity */ | ||
| 47 | 64, /* min_rmo_size */ | ||
| 48 | 0, /* min_rmo_percent */ | ||
| 49 | 40, /* max_pft_size */ | ||
| 50 | 1, /* splpar */ | ||
| 51 | -1, /* min_load */ | ||
| 52 | 0, /* new_mem_def */ | ||
| 53 | 1, /* ignore_my_client_config */ | ||
| 54 | }; | ||
| 55 | |||
| 56 | #define ROUNDUP(len) (((len) + 3) & ~3) | ||
| 57 | |||
| 34 | unsigned char buf[512]; | 58 | unsigned char buf[512]; |
| 35 | 59 | ||
| 36 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) | 60 | #define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) |
| @@ -69,7 +93,7 @@ main(int ac, char **av) | |||
| 69 | { | 93 | { |
| 70 | int fd, n, i; | 94 | int fd, n, i; |
| 71 | int ph, ps, np; | 95 | int ph, ps, np; |
| 72 | int nnote, ns; | 96 | int nnote, nnote2, ns; |
| 73 | 97 | ||
| 74 | if (ac != 2) { | 98 | if (ac != 2) { |
| 75 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); | 99 | fprintf(stderr, "Usage: %s elf-file\n", av[0]); |
| @@ -81,7 +105,8 @@ main(int ac, char **av) | |||
| 81 | exit(1); | 105 | exit(1); |
| 82 | } | 106 | } |
| 83 | 107 | ||
| 84 | nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; | 108 | nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr); |
| 109 | nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote); | ||
| 85 | 110 | ||
| 86 | n = read(fd, buf, sizeof(buf)); | 111 | n = read(fd, buf, sizeof(buf)); |
| 87 | if (n < 0) { | 112 | if (n < 0) { |
| @@ -104,7 +129,7 @@ main(int ac, char **av) | |||
| 104 | np = GET_16BE(E_PHNUM); | 129 | np = GET_16BE(E_PHNUM); |
| 105 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) | 130 | if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) |
| 106 | goto notelf; | 131 | goto notelf; |
| 107 | if (ph + (np + 1) * ps + nnote > n) | 132 | if (ph + (np + 2) * ps + nnote + nnote2 > n) |
| 108 | goto nospace; | 133 | goto nospace; |
| 109 | 134 | ||
| 110 | for (i = 0; i < np; ++i) { | 135 | for (i = 0; i < np; ++i) { |
| @@ -117,12 +142,12 @@ main(int ac, char **av) | |||
| 117 | } | 142 | } |
| 118 | 143 | ||
| 119 | /* XXX check that the area we want to use is all zeroes */ | 144 | /* XXX check that the area we want to use is all zeroes */ |
| 120 | for (i = 0; i < ps + nnote; ++i) | 145 | for (i = 0; i < 2 * ps + nnote + nnote2; ++i) |
| 121 | if (buf[ph + i] != 0) | 146 | if (buf[ph + i] != 0) |
| 122 | goto nospace; | 147 | goto nospace; |
| 123 | 148 | ||
| 124 | /* fill in the program header entry */ | 149 | /* fill in the program header entry */ |
| 125 | ns = ph + ps; | 150 | ns = ph + 2 * ps; |
| 126 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | 151 | PUT_32BE(ph + PH_TYPE, PT_NOTE); |
| 127 | PUT_32BE(ph + PH_OFFSET, ns); | 152 | PUT_32BE(ph + PH_OFFSET, ns); |
| 128 | PUT_32BE(ph + PH_FILESZ, nnote); | 153 | PUT_32BE(ph + PH_FILESZ, nnote); |
| @@ -134,11 +159,26 @@ main(int ac, char **av) | |||
| 134 | PUT_32BE(ns + 8, 0x1275); | 159 | PUT_32BE(ns + 8, 0x1275); |
| 135 | strcpy(&buf[ns + 12], arch); | 160 | strcpy(&buf[ns + 12], arch); |
| 136 | ns += 12 + strlen(arch) + 1; | 161 | ns += 12 + strlen(arch) + 1; |
| 137 | for (i = 0; i < N_DESCR; ++i) | 162 | for (i = 0; i < N_DESCR; ++i, ns += 4) |
| 138 | PUT_32BE(ns + i * 4, descr[i]); | 163 | PUT_32BE(ns, descr[i]); |
| 164 | |||
| 165 | /* fill in the second program header entry and the RPA note area */ | ||
| 166 | ph += ps; | ||
| 167 | PUT_32BE(ph + PH_TYPE, PT_NOTE); | ||
| 168 | PUT_32BE(ph + PH_OFFSET, ns); | ||
| 169 | PUT_32BE(ph + PH_FILESZ, nnote2); | ||
| 170 | |||
| 171 | /* fill in the note area we point to */ | ||
| 172 | PUT_32BE(ns, strlen(rpaname) + 1); | ||
| 173 | PUT_32BE(ns + 4, sizeof(rpanote)); | ||
| 174 | PUT_32BE(ns + 8, 0x12759999); | ||
| 175 | strcpy(&buf[ns + 12], rpaname); | ||
| 176 | ns += 12 + ROUNDUP(strlen(rpaname) + 1); | ||
| 177 | for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) | ||
| 178 | PUT_32BE(ns, rpanote[i]); | ||
| 139 | 179 | ||
| 140 | /* Update the number of program headers */ | 180 | /* Update the number of program headers */ |
| 141 | PUT_16BE(E_PHNUM, np + 1); | 181 | PUT_16BE(E_PHNUM, np + 2); |
| 142 | 182 | ||
| 143 | /* write back */ | 183 | /* write back */ |
| 144 | lseek(fd, (long) 0, SEEK_SET); | 184 | lseek(fd, (long) 0, SEEK_SET); |
| @@ -155,11 +195,11 @@ main(int ac, char **av) | |||
| 155 | exit(0); | 195 | exit(0); |
| 156 | 196 | ||
| 157 | notelf: | 197 | notelf: |
| 158 | fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); | 198 | fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); |
| 159 | exit(1); | 199 | exit(1); |
| 160 | 200 | ||
| 161 | nospace: | 201 | nospace: |
| 162 | fprintf(stderr, "sorry, I can't find space in %s to put the note\n", | 202 | fprintf(stderr, "sorry, I can't find space in %s to put the note\n", |
| 163 | av[0]); | 203 | av[1]); |
| 164 | exit(1); | 204 | exit(1); |
| 165 | } | 205 | } |
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index b0fa86ad8b1b..da12ea2ca464 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
| 15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
| 16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
| 17 | #include <asm/bootinfo.h> | ||
| 18 | 17 | ||
| 19 | extern void *finddevice(const char *); | 18 | extern void *finddevice(const char *); |
| 20 | extern int getprop(void *, const char *, void *, int); | 19 | extern int getprop(void *, const char *, void *, int); |
diff --git a/arch/ppc64/boot/start.c b/arch/ppc64/boot/start.c deleted file mode 100644 index ea247e79b55e..000000000000 --- a/arch/ppc64/boot/start.c +++ /dev/null | |||
| @@ -1,654 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) Paul Mackerras 1997. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version | ||
| 7 | * 2 of the License, or (at your option) any later version. | ||
| 8 | */ | ||
| 9 | #include <stdarg.h> | ||
| 10 | #include <linux/types.h> | ||
| 11 | #include <linux/string.h> | ||
| 12 | #include <linux/ctype.h> | ||
| 13 | |||
| 14 | #include <asm/div64.h> | ||
| 15 | |||
| 16 | int (*prom)(void *); | ||
| 17 | |||
| 18 | void *chosen_handle; | ||
| 19 | void *stdin; | ||
| 20 | void *stdout; | ||
| 21 | void *stderr; | ||
| 22 | |||
| 23 | void exit(void); | ||
| 24 | void *finddevice(const char *name); | ||
| 25 | int getprop(void *phandle, const char *name, void *buf, int buflen); | ||
| 26 | void chrpboot(int a1, int a2, void *prom); /* in main.c */ | ||
| 27 | |||
| 28 | void printk(char *fmt, ...); | ||
| 29 | |||
| 30 | void | ||
| 31 | start(int a1, int a2, void *promptr) | ||
| 32 | { | ||
| 33 | prom = (int (*)(void *)) promptr; | ||
| 34 | chosen_handle = finddevice("/chosen"); | ||
| 35 | if (chosen_handle == (void *) -1) | ||
| 36 | exit(); | ||
| 37 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) | ||
| 38 | exit(); | ||
| 39 | stderr = stdout; | ||
| 40 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | ||
| 41 | exit(); | ||
| 42 | |||
| 43 | chrpboot(a1, a2, promptr); | ||
| 44 | for (;;) | ||
| 45 | exit(); | ||
| 46 | } | ||
| 47 | |||
| 48 | int | ||
| 49 | write(void *handle, void *ptr, int nb) | ||
| 50 | { | ||
| 51 | struct prom_args { | ||
| 52 | char *service; | ||
| 53 | int nargs; | ||
| 54 | int nret; | ||
| 55 | void *ihandle; | ||
| 56 | void *addr; | ||
| 57 | int len; | ||
| 58 | int actual; | ||
| 59 | } args; | ||
| 60 | |||
| 61 | args.service = "write"; | ||
| 62 | args.nargs = 3; | ||
| 63 | args.nret = 1; | ||
| 64 | args.ihandle = handle; | ||
| 65 | args.addr = ptr; | ||
| 66 | args.len = nb; | ||
| 67 | args.actual = -1; | ||
| 68 | (*prom)(&args); | ||
| 69 | return args.actual; | ||
| 70 | } | ||
| 71 | |||
| 72 | int | ||
| 73 | read(void *handle, void *ptr, int nb) | ||
| 74 | { | ||
| 75 | struct prom_args { | ||
| 76 | char *service; | ||
| 77 | int nargs; | ||
| 78 | int nret; | ||
| 79 | void *ihandle; | ||
| 80 | void *addr; | ||
| 81 | int len; | ||
| 82 | int actual; | ||
| 83 | } args; | ||
| 84 | |||
| 85 | args.service = "read"; | ||
| 86 | args.nargs = 3; | ||
| 87 | args.nret = 1; | ||
| 88 | args.ihandle = handle; | ||
| 89 | args.addr = ptr; | ||
| 90 | args.len = nb; | ||
| 91 | args.actual = -1; | ||
| 92 | (*prom)(&args); | ||
| 93 | return args.actual; | ||
| 94 | } | ||
| 95 | |||
| 96 | void | ||
| 97 | exit() | ||
| 98 | { | ||
| 99 | struct prom_args { | ||
| 100 | char *service; | ||
| 101 | } args; | ||
| 102 | |||
| 103 | for (;;) { | ||
| 104 | args.service = "exit"; | ||
| 105 | (*prom)(&args); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | void | ||
| 110 | pause(void) | ||
| 111 | { | ||
| 112 | struct prom_args { | ||
| 113 | char *service; | ||
| 114 | } args; | ||
| 115 | |||
| 116 | args.service = "enter"; | ||
| 117 | (*prom)(&args); | ||
| 118 | } | ||
| 119 | |||
| 120 | void * | ||
| 121 | finddevice(const char *name) | ||
| 122 | { | ||
| 123 | struct prom_args { | ||
| 124 | char *service; | ||
| 125 | int nargs; | ||
| 126 | int nret; | ||
| 127 | const char *devspec; | ||
| 128 | void *phandle; | ||
| 129 | } args; | ||
| 130 | |||
| 131 | args.service = "finddevice"; | ||
| 132 | args.nargs = 1; | ||
| 133 | args.nret = 1; | ||
| 134 | args.devspec = name; | ||
| 135 | args.phandle = (void *) -1; | ||
| 136 | (*prom)(&args); | ||
| 137 | return args.phandle; | ||
| 138 | } | ||
| 139 | |||
| 140 | void * | ||
| 141 | claim(unsigned long virt, unsigned long size, unsigned long align) | ||
| 142 | { | ||
| 143 | struct prom_args { | ||
| 144 | char *service; | ||
| 145 | int nargs; | ||
| 146 | int nret; | ||
| 147 | unsigned int virt; | ||
| 148 | unsigned int size; | ||
| 149 | unsigned int align; | ||
| 150 | void *ret; | ||
| 151 | } args; | ||
| 152 | |||
| 153 | args.service = "claim"; | ||
| 154 | args.nargs = 3; | ||
| 155 | args.nret = 1; | ||
| 156 | args.virt = virt; | ||
| 157 | args.size = size; | ||
| 158 | args.align = align; | ||
| 159 | (*prom)(&args); | ||
| 160 | return args.ret; | ||
| 161 | } | ||
| 162 | |||
| 163 | int | ||
| 164 | getprop(void *phandle, const char *name, void *buf, int buflen) | ||
| 165 | { | ||
| 166 | struct prom_args { | ||
| 167 | char *service; | ||
| 168 | int nargs; | ||
| 169 | int nret; | ||
| 170 | void *phandle; | ||
| 171 | const char *name; | ||
| 172 | void *buf; | ||
| 173 | int buflen; | ||
| 174 | int size; | ||
| 175 | } args; | ||
| 176 | |||
| 177 | args.service = "getprop"; | ||
| 178 | args.nargs = 4; | ||
| 179 | args.nret = 1; | ||
| 180 | args.phandle = phandle; | ||
| 181 | args.name = name; | ||
| 182 | args.buf = buf; | ||
| 183 | args.buflen = buflen; | ||
| 184 | args.size = -1; | ||
| 185 | (*prom)(&args); | ||
| 186 | return args.size; | ||
| 187 | } | ||
| 188 | |||
| 189 | int | ||
| 190 | putc(int c, void *f) | ||
| 191 | { | ||
| 192 | char ch = c; | ||
| 193 | |||
| 194 | if (c == '\n') | ||
| 195 | putc('\r', f); | ||
| 196 | return write(f, &ch, 1) == 1? c: -1; | ||
| 197 | } | ||
| 198 | |||
| 199 | int | ||
| 200 | putchar(int c) | ||
| 201 | { | ||
| 202 | return putc(c, stdout); | ||
| 203 | } | ||
| 204 | |||
| 205 | int | ||
| 206 | fputs(char *str, void *f) | ||
| 207 | { | ||
| 208 | int n = strlen(str); | ||
| 209 | |||
| 210 | return write(f, str, n) == n? 0: -1; | ||
| 211 | } | ||
| 212 | |||
| 213 | int | ||
| 214 | readchar(void) | ||
| 215 | { | ||
| 216 | char ch; | ||
| 217 | |||
| 218 | for (;;) { | ||
| 219 | switch (read(stdin, &ch, 1)) { | ||
| 220 | case 1: | ||
| 221 | return ch; | ||
| 222 | case -1: | ||
| 223 | printk("read(stdin) returned -1\r\n"); | ||
| 224 | return -1; | ||
| 225 | } | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | static char line[256]; | ||
| 230 | static char *lineptr; | ||
| 231 | static int lineleft; | ||
| 232 | |||
| 233 | int | ||
| 234 | getchar(void) | ||
| 235 | { | ||
| 236 | int c; | ||
| 237 | |||
| 238 | if (lineleft == 0) { | ||
| 239 | lineptr = line; | ||
| 240 | for (;;) { | ||
| 241 | c = readchar(); | ||
| 242 | if (c == -1 || c == 4) | ||
| 243 | break; | ||
| 244 | if (c == '\r' || c == '\n') { | ||
| 245 | *lineptr++ = '\n'; | ||
| 246 | putchar('\n'); | ||
| 247 | break; | ||
| 248 | } | ||
| 249 | switch (c) { | ||
| 250 | case 0177: | ||
| 251 | case '\b': | ||
| 252 | if (lineptr > line) { | ||
| 253 | putchar('\b'); | ||
| 254 | putchar(' '); | ||
| 255 | putchar('\b'); | ||
| 256 | --lineptr; | ||
| 257 | } | ||
| 258 | break; | ||
| 259 | case 'U' & 0x1F: | ||
| 260 | while (lineptr > line) { | ||
| 261 | putchar('\b'); | ||
| 262 | putchar(' '); | ||
| 263 | putchar('\b'); | ||
| 264 | --lineptr; | ||
| 265 | } | ||
| 266 | break; | ||
| 267 | default: | ||
| 268 | if (lineptr >= &line[sizeof(line) - 1]) | ||
| 269 | putchar('\a'); | ||
| 270 | else { | ||
| 271 | putchar(c); | ||
| 272 | *lineptr++ = c; | ||
| 273 | } | ||
| 274 | } | ||
| 275 | } | ||
| 276 | lineleft = lineptr - line; | ||
| 277 | lineptr = line; | ||
| 278 | } | ||
| 279 | if (lineleft == 0) | ||
| 280 | return -1; | ||
| 281 | --lineleft; | ||
| 282 | return *lineptr++; | ||
| 283 | } | ||
| 284 | |||
| 285 | |||
| 286 | |||
| 287 | /* String functions lifted from lib/vsprintf.c and lib/ctype.c */ | ||
| 288 | unsigned char _ctype[] = { | ||
| 289 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ | ||
| 290 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ | ||
| 291 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ | ||
| 292 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ | ||
| 293 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ | ||
| 294 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ | ||
| 295 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ | ||
| 296 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ | ||
| 297 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ | ||
| 298 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ | ||
| 299 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ | ||
| 300 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ | ||
| 301 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ | ||
| 302 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ | ||
| 303 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ | ||
| 304 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ | ||
| 305 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ | ||
| 306 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ | ||
| 307 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ | ||
| 308 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ | ||
| 309 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ | ||
| 310 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ | ||
| 311 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ | ||
| 312 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ | ||
| 313 | |||
| 314 | size_t strnlen(const char * s, size_t count) | ||
| 315 | { | ||
| 316 | const char *sc; | ||
| 317 | |||
| 318 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
| 319 | /* nothing */; | ||
| 320 | return sc - s; | ||
| 321 | } | ||
| 322 | |||
| 323 | unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) | ||
| 324 | { | ||
| 325 | unsigned long result = 0,value; | ||
| 326 | |||
| 327 | if (!base) { | ||
| 328 | base = 10; | ||
| 329 | if (*cp == '0') { | ||
| 330 | base = 8; | ||
| 331 | cp++; | ||
| 332 | if ((*cp == 'x') && isxdigit(cp[1])) { | ||
| 333 | cp++; | ||
| 334 | base = 16; | ||
| 335 | } | ||
| 336 | } | ||
| 337 | } | ||
| 338 | while (isxdigit(*cp) && | ||
| 339 | (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { | ||
| 340 | result = result*base + value; | ||
| 341 | cp++; | ||
| 342 | } | ||
| 343 | if (endp) | ||
| 344 | *endp = (char *)cp; | ||
| 345 | return result; | ||
| 346 | } | ||
| 347 | |||
| 348 | long simple_strtol(const char *cp,char **endp,unsigned int base) | ||
| 349 | { | ||
| 350 | if(*cp=='-') | ||
| 351 | return -simple_strtoul(cp+1,endp,base); | ||
| 352 | return simple_strtoul(cp,endp,base); | ||
| 353 | } | ||
| 354 | |||
| 355 | static int skip_atoi(const char **s) | ||
| 356 | { | ||
| 357 | int i=0; | ||
| 358 | |||
| 359 | while (isdigit(**s)) | ||
| 360 | i = i*10 + *((*s)++) - '0'; | ||
| 361 | return i; | ||
| 362 | } | ||
| 363 | |||
| 364 | #define ZEROPAD 1 /* pad with zero */ | ||
| 365 | #define SIGN 2 /* unsigned/signed long */ | ||
| 366 | #define PLUS 4 /* show plus */ | ||
| 367 | #define SPACE 8 /* space if plus */ | ||
| 368 | #define LEFT 16 /* left justified */ | ||
| 369 | #define SPECIAL 32 /* 0x */ | ||
| 370 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
| 371 | |||
| 372 | static char * number(char * str, long long num, int base, int size, int precision, int type) | ||
| 373 | { | ||
| 374 | char c,sign,tmp[66]; | ||
| 375 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | ||
| 376 | int i; | ||
| 377 | |||
| 378 | if (type & LARGE) | ||
| 379 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
| 380 | if (type & LEFT) | ||
| 381 | type &= ~ZEROPAD; | ||
| 382 | if (base < 2 || base > 36) | ||
| 383 | return 0; | ||
| 384 | c = (type & ZEROPAD) ? '0' : ' '; | ||
| 385 | sign = 0; | ||
| 386 | if (type & SIGN) { | ||
| 387 | if (num < 0) { | ||
| 388 | sign = '-'; | ||
| 389 | num = -num; | ||
| 390 | size--; | ||
| 391 | } else if (type & PLUS) { | ||
| 392 | sign = '+'; | ||
| 393 | size--; | ||
| 394 | } else if (type & SPACE) { | ||
| 395 | sign = ' '; | ||
| 396 | size--; | ||
| 397 | } | ||
| 398 | } | ||
| 399 | if (type & SPECIAL) { | ||
| 400 | if (base == 16) | ||
| 401 | size -= 2; | ||
| 402 | else if (base == 8) | ||
| 403 | size--; | ||
| 404 | } | ||
| 405 | i = 0; | ||
| 406 | if (num == 0) | ||
| 407 | tmp[i++]='0'; | ||
| 408 | else while (num != 0) | ||
| 409 | tmp[i++] = digits[do_div(num,base)]; | ||
| 410 | if (i > precision) | ||
| 411 | precision = i; | ||
| 412 | size -= precision; | ||
| 413 | if (!(type&(ZEROPAD+LEFT))) | ||
| 414 | while(size-->0) | ||
| 415 | *str++ = ' '; | ||
| 416 | if (sign) | ||
| 417 | *str++ = sign; | ||
| 418 | if (type & SPECIAL) { | ||
| 419 | if (base==8) | ||
| 420 | *str++ = '0'; | ||
| 421 | else if (base==16) { | ||
| 422 | *str++ = '0'; | ||
| 423 | *str++ = digits[33]; | ||
| 424 | } | ||
| 425 | } | ||
| 426 | if (!(type & LEFT)) | ||
| 427 | while (size-- > 0) | ||
| 428 | *str++ = c; | ||
| 429 | while (i < precision--) | ||
| 430 | *str++ = '0'; | ||
| 431 | while (i-- > 0) | ||
| 432 | *str++ = tmp[i]; | ||
| 433 | while (size-- > 0) | ||
| 434 | *str++ = ' '; | ||
| 435 | return str; | ||
| 436 | } | ||
| 437 | |||
| 438 | /* Forward decl. needed for IP address printing stuff... */ | ||
| 439 | int sprintf(char * buf, const char *fmt, ...); | ||
| 440 | |||
| 441 | int vsprintf(char *buf, const char *fmt, va_list args) | ||
| 442 | { | ||
| 443 | int len; | ||
| 444 | unsigned long long num; | ||
| 445 | int i, base; | ||
| 446 | char * str; | ||
| 447 | const char *s; | ||
| 448 | |||
| 449 | int flags; /* flags to number() */ | ||
| 450 | |||
| 451 | int field_width; /* width of output field */ | ||
| 452 | int precision; /* min. # of digits for integers; max | ||
| 453 | number of chars for from string */ | ||
| 454 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
| 455 | /* 'z' support added 23/7/1999 S.H. */ | ||
| 456 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
| 457 | |||
| 458 | |||
| 459 | for (str=buf ; *fmt ; ++fmt) { | ||
| 460 | if (*fmt != '%') { | ||
| 461 | *str++ = *fmt; | ||
| 462 | continue; | ||
| 463 | } | ||
| 464 | |||
| 465 | /* process flags */ | ||
| 466 | flags = 0; | ||
| 467 | repeat: | ||
| 468 | ++fmt; /* this also skips first '%' */ | ||
| 469 | switch (*fmt) { | ||
| 470 | case '-': flags |= LEFT; goto repeat; | ||
| 471 | case '+': flags |= PLUS; goto repeat; | ||
| 472 | case ' ': flags |= SPACE; goto repeat; | ||
| 473 | case '#': flags |= SPECIAL; goto repeat; | ||
| 474 | case '0': flags |= ZEROPAD; goto repeat; | ||
| 475 | } | ||
| 476 | |||
| 477 | /* get field width */ | ||
| 478 | field_width = -1; | ||
| 479 | if (isdigit(*fmt)) | ||
| 480 | field_width = skip_atoi(&fmt); | ||
| 481 | else if (*fmt == '*') { | ||
| 482 | ++fmt; | ||
| 483 | /* it's the next argument */ | ||
| 484 | field_width = va_arg(args, int); | ||
| 485 | if (field_width < 0) { | ||
| 486 | field_width = -field_width; | ||
| 487 | flags |= LEFT; | ||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | /* get the precision */ | ||
| 492 | precision = -1; | ||
| 493 | if (*fmt == '.') { | ||
| 494 | ++fmt; | ||
| 495 | if (isdigit(*fmt)) | ||
| 496 | precision = skip_atoi(&fmt); | ||
| 497 | else if (*fmt == '*') { | ||
| 498 | ++fmt; | ||
| 499 | /* it's the next argument */ | ||
| 500 | precision = va_arg(args, int); | ||
| 501 | } | ||
| 502 | if (precision < 0) | ||
| 503 | precision = 0; | ||
| 504 | } | ||
| 505 | |||
| 506 | /* get the conversion qualifier */ | ||
| 507 | qualifier = -1; | ||
| 508 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
| 509 | qualifier = *fmt; | ||
| 510 | ++fmt; | ||
| 511 | } | ||
| 512 | |||
| 513 | /* default base */ | ||
| 514 | base = 10; | ||
| 515 | |||
| 516 | switch (*fmt) { | ||
| 517 | case 'c': | ||
| 518 | if (!(flags & LEFT)) | ||
| 519 | while (--field_width > 0) | ||
| 520 | *str++ = ' '; | ||
| 521 | *str++ = (unsigned char) va_arg(args, int); | ||
| 522 | while (--field_width > 0) | ||
| 523 | *str++ = ' '; | ||
| 524 | continue; | ||
| 525 | |||
| 526 | case 's': | ||
| 527 | s = va_arg(args, char *); | ||
| 528 | if (!s) | ||
| 529 | s = "<NULL>"; | ||
| 530 | |||
| 531 | len = strnlen(s, precision); | ||
| 532 | |||
| 533 | if (!(flags & LEFT)) | ||
| 534 | while (len < field_width--) | ||
| 535 | *str++ = ' '; | ||
| 536 | for (i = 0; i < len; ++i) | ||
| 537 | *str++ = *s++; | ||
| 538 | while (len < field_width--) | ||
| 539 | *str++ = ' '; | ||
| 540 | continue; | ||
| 541 | |||
| 542 | case 'p': | ||
| 543 | if (field_width == -1) { | ||
| 544 | field_width = 2*sizeof(void *); | ||
| 545 | flags |= ZEROPAD; | ||
| 546 | } | ||
| 547 | str = number(str, | ||
| 548 | (unsigned long) va_arg(args, void *), 16, | ||
| 549 | field_width, precision, flags); | ||
| 550 | continue; | ||
| 551 | |||
| 552 | |||
| 553 | case 'n': | ||
| 554 | if (qualifier == 'l') { | ||
| 555 | long * ip = va_arg(args, long *); | ||
| 556 | *ip = (str - buf); | ||
| 557 | } else if (qualifier == 'Z') { | ||
| 558 | size_t * ip = va_arg(args, size_t *); | ||
| 559 | *ip = (str - buf); | ||
| 560 | } else { | ||
| 561 | int * ip = va_arg(args, int *); | ||
| 562 | *ip = (str - buf); | ||
| 563 | } | ||
| 564 | continue; | ||
| 565 | |||
| 566 | case '%': | ||
| 567 | *str++ = '%'; | ||
| 568 | continue; | ||
| 569 | |||
| 570 | /* integer number formats - set up the flags and "break" */ | ||
| 571 | case 'o': | ||
| 572 | base = 8; | ||
| 573 | break; | ||
| 574 | |||
| 575 | case 'X': | ||
| 576 | flags |= LARGE; | ||
| 577 | case 'x': | ||
| 578 | base = 16; | ||
| 579 | break; | ||
| 580 | |||
| 581 | case 'd': | ||
| 582 | case 'i': | ||
| 583 | flags |= SIGN; | ||
| 584 | case 'u': | ||
| 585 | break; | ||
| 586 | |||
| 587 | default: | ||
| 588 | *str++ = '%'; | ||
| 589 | if (*fmt) | ||
| 590 | *str++ = *fmt; | ||
| 591 | else | ||
| 592 | --fmt; | ||
| 593 | continue; | ||
| 594 | } | ||
| 595 | if (qualifier == 'L') | ||
| 596 | num = va_arg(args, long long); | ||
| 597 | else if (qualifier == 'l') { | ||
| 598 | num = va_arg(args, unsigned long); | ||
| 599 | if (flags & SIGN) | ||
| 600 | num = (signed long) num; | ||
| 601 | } else if (qualifier == 'Z') { | ||
| 602 | num = va_arg(args, size_t); | ||
| 603 | } else if (qualifier == 'h') { | ||
| 604 | num = (unsigned short) va_arg(args, int); | ||
| 605 | if (flags & SIGN) | ||
| 606 | num = (signed short) num; | ||
| 607 | } else { | ||
| 608 | num = va_arg(args, unsigned int); | ||
| 609 | if (flags & SIGN) | ||
| 610 | num = (signed int) num; | ||
| 611 | } | ||
| 612 | str = number(str, num, base, field_width, precision, flags); | ||
| 613 | } | ||
| 614 | *str = '\0'; | ||
| 615 | return str-buf; | ||
| 616 | } | ||
| 617 | |||
| 618 | int sprintf(char * buf, const char *fmt, ...) | ||
| 619 | { | ||
| 620 | va_list args; | ||
| 621 | int i; | ||
| 622 | |||
| 623 | va_start(args, fmt); | ||
| 624 | i=vsprintf(buf,fmt,args); | ||
| 625 | va_end(args); | ||
| 626 | return i; | ||
| 627 | } | ||
| 628 | |||
| 629 | static char sprint_buf[1024]; | ||
| 630 | |||
| 631 | void | ||
| 632 | printk(char *fmt, ...) | ||
| 633 | { | ||
| 634 | va_list args; | ||
| 635 | int n; | ||
| 636 | |||
| 637 | va_start(args, fmt); | ||
| 638 | n = vsprintf(sprint_buf, fmt, args); | ||
| 639 | va_end(args); | ||
| 640 | write(stdout, sprint_buf, n); | ||
| 641 | } | ||
| 642 | |||
| 643 | int | ||
| 644 | printf(char *fmt, ...) | ||
| 645 | { | ||
| 646 | va_list args; | ||
| 647 | int n; | ||
| 648 | |||
| 649 | va_start(args, fmt); | ||
| 650 | n = vsprintf(sprint_buf, fmt, args); | ||
| 651 | va_end(args); | ||
| 652 | write(stdout, sprint_buf, n); | ||
| 653 | return n; | ||
| 654 | } | ||
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c index 9802beefa217..f8f19637f73f 100644 --- a/arch/ppc64/kernel/HvLpEvent.c +++ b/arch/ppc64/kernel/HvLpEvent.c | |||
| @@ -45,7 +45,7 @@ int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType ) | |||
| 45 | /* We now sleep until all other CPUs have scheduled. This ensures that | 45 | /* We now sleep until all other CPUs have scheduled. This ensures that |
| 46 | * the deletion is seen by all other CPUs, and that the deleted handler | 46 | * the deletion is seen by all other CPUs, and that the deleted handler |
| 47 | * isn't still running on another CPU when we return. */ | 47 | * isn't still running on another CPU when we return. */ |
| 48 | synchronize_kernel(); | 48 | synchronize_rcu(); |
| 49 | } | 49 | } |
| 50 | } | 50 | } |
| 51 | return rc; | 51 | return rc; |
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 90b41f48d21c..b944717c1dbd 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | .text | 32 | .text |
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | * Returns (address we're running at) - (address we were linked at) | 35 | * Returns (address we were linked at) - (address we are running at) |
| 36 | * for use before the text and data are mapped to KERNELBASE. | 36 | * for use before the text and data are mapped to KERNELBASE. |
| 37 | */ | 37 | */ |
| 38 | 38 | ||
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index b9069c2d1933..4e71781a4414 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c | |||
| @@ -339,9 +339,9 @@ static int nvram_remove_os_partition(void) | |||
| 339 | static int nvram_create_os_partition(void) | 339 | static int nvram_create_os_partition(void) |
| 340 | { | 340 | { |
| 341 | struct list_head * p; | 341 | struct list_head * p; |
| 342 | struct nvram_partition * part; | 342 | struct nvram_partition *part = NULL; |
| 343 | struct nvram_partition * new_part = NULL; | 343 | struct nvram_partition *new_part = NULL; |
| 344 | struct nvram_partition * free_part = NULL; | 344 | struct nvram_partition *free_part = NULL; |
| 345 | int seq_init[2] = { 0, 0 }; | 345 | int seq_init[2] = { 0, 0 }; |
| 346 | loff_t tmp_index; | 346 | loff_t tmp_index; |
| 347 | long size = 0; | 347 | long size = 0; |
| @@ -364,13 +364,11 @@ static int nvram_create_os_partition(void) | |||
| 364 | free_part = part; | 364 | free_part = part; |
| 365 | } | 365 | } |
| 366 | } | 366 | } |
| 367 | if (!size) { | 367 | if (!size) |
| 368 | return -ENOSPC; | 368 | return -ENOSPC; |
| 369 | } | ||
| 370 | 369 | ||
| 371 | /* Create our OS partition */ | 370 | /* Create our OS partition */ |
| 372 | new_part = (struct nvram_partition *) | 371 | new_part = kmalloc(sizeof(*new_part), GFP_KERNEL); |
| 373 | kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); | ||
| 374 | if (!new_part) { | 372 | if (!new_part) { |
| 375 | printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n"); | 373 | printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n"); |
| 376 | return -ENOMEM; | 374 | return -ENOMEM; |
| @@ -379,7 +377,7 @@ static int nvram_create_os_partition(void) | |||
| 379 | new_part->index = free_part->index; | 377 | new_part->index = free_part->index; |
| 380 | new_part->header.signature = NVRAM_SIG_OS; | 378 | new_part->header.signature = NVRAM_SIG_OS; |
| 381 | new_part->header.length = size; | 379 | new_part->header.length = size; |
| 382 | sprintf(new_part->header.name, "ppc64,linux"); | 380 | strcpy(new_part->header.name, "ppc64,linux"); |
| 383 | new_part->header.checksum = nvram_checksum(&new_part->header); | 381 | new_part->header.checksum = nvram_checksum(&new_part->header); |
| 384 | 382 | ||
| 385 | rc = nvram_write_header(new_part); | 383 | rc = nvram_write_header(new_part); |
| @@ -394,7 +392,8 @@ static int nvram_create_os_partition(void) | |||
| 394 | tmp_index = new_part->index + NVRAM_HEADER_LEN; | 392 | tmp_index = new_part->index + NVRAM_HEADER_LEN; |
| 395 | rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index); | 393 | rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index); |
| 396 | if (rc <= 0) { | 394 | if (rc <= 0) { |
| 397 | printk(KERN_ERR "nvram_create_os_partition: nvram_write failed (%d)\n", rc); | 395 | printk(KERN_ERR "nvram_create_os_partition: nvram_write " |
| 396 | "failed (%d)\n", rc); | ||
| 398 | return rc; | 397 | return rc; |
| 399 | } | 398 | } |
| 400 | 399 | ||
diff --git a/arch/ppc64/kernel/pSeries_hvCall.S b/arch/ppc64/kernel/pSeries_hvCall.S index 0715d3038019..176e8da76466 100644 --- a/arch/ppc64/kernel/pSeries_hvCall.S +++ b/arch/ppc64/kernel/pSeries_hvCall.S | |||
| @@ -28,6 +28,8 @@ | |||
| 28 | unsigned long *out3); R10 | 28 | unsigned long *out3); R10 |
| 29 | */ | 29 | */ |
| 30 | _GLOBAL(plpar_hcall) | 30 | _GLOBAL(plpar_hcall) |
| 31 | HMT_MEDIUM | ||
| 32 | |||
| 31 | mfcr r0 | 33 | mfcr r0 |
| 32 | 34 | ||
| 33 | std r8,STK_PARM(r8)(r1) /* Save out ptrs */ | 35 | std r8,STK_PARM(r8)(r1) /* Save out ptrs */ |
| @@ -53,6 +55,8 @@ _GLOBAL(plpar_hcall) | |||
| 53 | 55 | ||
| 54 | /* Simple interface with no output values (other than status) */ | 56 | /* Simple interface with no output values (other than status) */ |
| 55 | _GLOBAL(plpar_hcall_norets) | 57 | _GLOBAL(plpar_hcall_norets) |
| 58 | HMT_MEDIUM | ||
| 59 | |||
| 56 | mfcr r0 | 60 | mfcr r0 |
| 57 | stw r0,8(r1) | 61 | stw r0,8(r1) |
| 58 | 62 | ||
| @@ -75,6 +79,8 @@ _GLOBAL(plpar_hcall_norets) | |||
| 75 | unsigned long *out1); 120(R1) | 79 | unsigned long *out1); 120(R1) |
| 76 | */ | 80 | */ |
| 77 | _GLOBAL(plpar_hcall_8arg_2ret) | 81 | _GLOBAL(plpar_hcall_8arg_2ret) |
| 82 | HMT_MEDIUM | ||
| 83 | |||
| 78 | mfcr r0 | 84 | mfcr r0 |
| 79 | ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ | 85 | ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ |
| 80 | stw r0,8(r1) | 86 | stw r0,8(r1) |
| @@ -99,6 +105,8 @@ _GLOBAL(plpar_hcall_8arg_2ret) | |||
| 99 | unsigned long *out4); 112(R1) | 105 | unsigned long *out4); 112(R1) |
| 100 | */ | 106 | */ |
| 101 | _GLOBAL(plpar_hcall_4out) | 107 | _GLOBAL(plpar_hcall_4out) |
| 108 | HMT_MEDIUM | ||
| 109 | |||
| 102 | mfcr r0 | 110 | mfcr r0 |
| 103 | stw r0,8(r1) | 111 | stw r0,8(r1) |
| 104 | 112 | ||
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index c60d8cb2b84d..fbad349ec58c 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c | |||
| @@ -326,13 +326,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
| 326 | 326 | ||
| 327 | cpu_clear(cpu, of_spin_map); | 327 | cpu_clear(cpu, of_spin_map); |
| 328 | 328 | ||
| 329 | /* | ||
| 330 | * Put the calling processor into the GIQ. This is really only | ||
| 331 | * necessary from a secondary thread as the OF start-cpu interface | ||
| 332 | * performs this function for us on primary threads. | ||
| 333 | */ | ||
| 334 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
| 335 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); | ||
| 336 | } | 329 | } |
| 337 | 330 | ||
| 338 | static DEFINE_SPINLOCK(timebase_lock); | 331 | static DEFINE_SPINLOCK(timebase_lock); |
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index be3cc387c1ec..d786d4b6af0b 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
| @@ -438,7 +438,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
| 438 | int i; | 438 | int i; |
| 439 | 439 | ||
| 440 | if (page_is_ram(offset >> PAGE_SHIFT)) | 440 | if (page_is_ram(offset >> PAGE_SHIFT)) |
| 441 | return prot; | 441 | return __pgprot(prot); |
| 442 | 442 | ||
| 443 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | 443 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; |
| 444 | 444 | ||
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 45a4ad08fbc2..eb6538b58008 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
| @@ -321,6 +321,10 @@ static int __devinit finish_node_interrupts(struct device_node *np, | |||
| 321 | char *name = get_property(ic->parent, "name", NULL); | 321 | char *name = get_property(ic->parent, "name", NULL); |
| 322 | if (name && !strcmp(name, "u3")) | 322 | if (name && !strcmp(name, "u3")) |
| 323 | np->intrs[intrcount].line += 128; | 323 | np->intrs[intrcount].line += 128; |
| 324 | else if (!(name && !strcmp(name, "mac-io"))) | ||
| 325 | /* ignore other cascaded controllers, such as | ||
| 326 | the k2-sata-root */ | ||
| 327 | break; | ||
| 324 | } | 328 | } |
| 325 | np->intrs[intrcount].sense = 1; | 329 | np->intrs[intrcount].sense = 1; |
| 326 | if (n > 1) | 330 | if (n > 1) |
| @@ -830,7 +834,7 @@ void __init unflatten_device_tree(void) | |||
| 830 | { | 834 | { |
| 831 | unsigned long start, mem, size; | 835 | unsigned long start, mem, size; |
| 832 | struct device_node **allnextp = &allnodes; | 836 | struct device_node **allnextp = &allnodes; |
| 833 | char *p; | 837 | char *p = NULL; |
| 834 | int l = 0; | 838 | int l = 0; |
| 835 | 839 | ||
| 836 | DBG(" -> unflatten_device_tree()\n"); | 840 | DBG(" -> unflatten_device_tree()\n"); |
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 8dffa9ae2623..35ec42de962e 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c | |||
| @@ -493,6 +493,113 @@ static void __init early_cmdline_parse(void) | |||
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | /* | 495 | /* |
| 496 | * To tell the firmware what our capabilities are, we have to pass | ||
| 497 | * it a fake 32-bit ELF header containing a couple of PT_NOTE sections | ||
| 498 | * that contain structures that contain the actual values. | ||
| 499 | */ | ||
| 500 | static struct fake_elf { | ||
| 501 | Elf32_Ehdr elfhdr; | ||
| 502 | Elf32_Phdr phdr[2]; | ||
| 503 | struct chrpnote { | ||
| 504 | u32 namesz; | ||
| 505 | u32 descsz; | ||
| 506 | u32 type; | ||
| 507 | char name[8]; /* "PowerPC" */ | ||
| 508 | struct chrpdesc { | ||
| 509 | u32 real_mode; | ||
| 510 | u32 real_base; | ||
| 511 | u32 real_size; | ||
| 512 | u32 virt_base; | ||
| 513 | u32 virt_size; | ||
| 514 | u32 load_base; | ||
| 515 | } chrpdesc; | ||
| 516 | } chrpnote; | ||
| 517 | struct rpanote { | ||
| 518 | u32 namesz; | ||
| 519 | u32 descsz; | ||
| 520 | u32 type; | ||
| 521 | char name[24]; /* "IBM,RPA-Client-Config" */ | ||
| 522 | struct rpadesc { | ||
| 523 | u32 lpar_affinity; | ||
| 524 | u32 min_rmo_size; | ||
| 525 | u32 min_rmo_percent; | ||
| 526 | u32 max_pft_size; | ||
| 527 | u32 splpar; | ||
| 528 | u32 min_load; | ||
| 529 | u32 new_mem_def; | ||
| 530 | u32 ignore_me; | ||
| 531 | } rpadesc; | ||
| 532 | } rpanote; | ||
| 533 | } fake_elf = { | ||
| 534 | .elfhdr = { | ||
| 535 | .e_ident = { 0x7f, 'E', 'L', 'F', | ||
| 536 | ELFCLASS32, ELFDATA2MSB, EV_CURRENT }, | ||
| 537 | .e_type = ET_EXEC, /* yeah right */ | ||
| 538 | .e_machine = EM_PPC, | ||
| 539 | .e_version = EV_CURRENT, | ||
| 540 | .e_phoff = offsetof(struct fake_elf, phdr), | ||
| 541 | .e_phentsize = sizeof(Elf32_Phdr), | ||
| 542 | .e_phnum = 2 | ||
| 543 | }, | ||
| 544 | .phdr = { | ||
| 545 | [0] = { | ||
| 546 | .p_type = PT_NOTE, | ||
| 547 | .p_offset = offsetof(struct fake_elf, chrpnote), | ||
| 548 | .p_filesz = sizeof(struct chrpnote) | ||
| 549 | }, [1] = { | ||
| 550 | .p_type = PT_NOTE, | ||
| 551 | .p_offset = offsetof(struct fake_elf, rpanote), | ||
| 552 | .p_filesz = sizeof(struct rpanote) | ||
| 553 | } | ||
| 554 | }, | ||
| 555 | .chrpnote = { | ||
| 556 | .namesz = sizeof("PowerPC"), | ||
| 557 | .descsz = sizeof(struct chrpdesc), | ||
| 558 | .type = 0x1275, | ||
| 559 | .name = "PowerPC", | ||
| 560 | .chrpdesc = { | ||
| 561 | .real_mode = ~0U, /* ~0 means "don't care" */ | ||
| 562 | .real_base = ~0U, | ||
| 563 | .real_size = ~0U, | ||
| 564 | .virt_base = ~0U, | ||
| 565 | .virt_size = ~0U, | ||
| 566 | .load_base = ~0U | ||
| 567 | }, | ||
| 568 | }, | ||
| 569 | .rpanote = { | ||
| 570 | .namesz = sizeof("IBM,RPA-Client-Config"), | ||
| 571 | .descsz = sizeof(struct rpadesc), | ||
| 572 | .type = 0x12759999, | ||
| 573 | .name = "IBM,RPA-Client-Config", | ||
| 574 | .rpadesc = { | ||
| 575 | .lpar_affinity = 0, | ||
| 576 | .min_rmo_size = 64, /* in megabytes */ | ||
| 577 | .min_rmo_percent = 0, | ||
| 578 | .max_pft_size = 48, /* 2^48 bytes max PFT size */ | ||
| 579 | .splpar = 1, | ||
| 580 | .min_load = ~0U, | ||
| 581 | .new_mem_def = 0 | ||
| 582 | } | ||
| 583 | } | ||
| 584 | }; | ||
| 585 | |||
| 586 | static void __init prom_send_capabilities(void) | ||
| 587 | { | ||
| 588 | unsigned long offset = reloc_offset(); | ||
| 589 | ihandle elfloader; | ||
| 590 | int ret; | ||
| 591 | |||
| 592 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); | ||
| 593 | if (elfloader == 0) { | ||
| 594 | prom_printf("couldn't open /packages/elf-loader\n"); | ||
| 595 | return; | ||
| 596 | } | ||
| 597 | ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), | ||
| 598 | elfloader, ADDR(&fake_elf)); | ||
| 599 | call_prom("close", 1, 0, elfloader); | ||
| 600 | } | ||
| 601 | |||
| 602 | /* | ||
| 496 | * Memory allocation strategy... our layout is normally: | 603 | * Memory allocation strategy... our layout is normally: |
| 497 | * | 604 | * |
| 498 | * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd | 605 | * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd |
| @@ -1448,6 +1555,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
| 1448 | } | 1555 | } |
| 1449 | } | 1556 | } |
| 1450 | 1557 | ||
| 1558 | /* | ||
| 1559 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
| 1560 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
| 1561 | */ | ||
| 1562 | #define MAX_PROPERTY_NAME 64 | ||
| 1563 | |||
| 1451 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | 1564 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, |
| 1452 | unsigned long *mem_end) | 1565 | unsigned long *mem_end) |
| 1453 | { | 1566 | { |
| @@ -1457,7 +1570,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
| 1457 | unsigned long soff; | 1570 | unsigned long soff; |
| 1458 | unsigned char *valp; | 1571 | unsigned char *valp; |
| 1459 | unsigned long offset = reloc_offset(); | 1572 | unsigned long offset = reloc_offset(); |
| 1460 | char pname[32]; | 1573 | char pname[MAX_PROPERTY_NAME]; |
| 1461 | char *path; | 1574 | char *path; |
| 1462 | 1575 | ||
| 1463 | path = RELOC(prom_scratch); | 1576 | path = RELOC(prom_scratch); |
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c index 354a287c67eb..9f8c6087ae56 100644 --- a/arch/ppc64/kernel/ptrace.c +++ b/arch/ppc64/kernel/ptrace.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
| 29 | #include <linux/audit.h> | 29 | #include <linux/audit.h> |
| 30 | #include <linux/seccomp.h> | 30 | #include <linux/seccomp.h> |
| 31 | #include <linux/signal.h> | ||
| 31 | 32 | ||
| 32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
| 33 | #include <asm/page.h> | 34 | #include <asm/page.h> |
| @@ -162,7 +163,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
| 162 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 163 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
| 163 | case PTRACE_CONT: { /* restart after signal. */ | 164 | case PTRACE_CONT: { /* restart after signal. */ |
| 164 | ret = -EIO; | 165 | ret = -EIO; |
| 165 | if ((unsigned long) data > _NSIG) | 166 | if (!valid_signal(data)) |
| 166 | break; | 167 | break; |
| 167 | if (request == PTRACE_SYSCALL) | 168 | if (request == PTRACE_SYSCALL) |
| 168 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 169 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
| @@ -194,7 +195,7 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
| 194 | 195 | ||
| 195 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 196 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
| 196 | ret = -EIO; | 197 | ret = -EIO; |
| 197 | if ((unsigned long) data > _NSIG) | 198 | if (!valid_signal(data)) |
| 198 | break; | 199 | break; |
| 199 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 200 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
| 200 | set_single_step(child); | 201 | set_single_step(child); |
| @@ -304,14 +305,17 @@ static void do_syscall_trace(void) | |||
| 304 | 305 | ||
| 305 | void do_syscall_trace_enter(struct pt_regs *regs) | 306 | void do_syscall_trace_enter(struct pt_regs *regs) |
| 306 | { | 307 | { |
| 308 | if (test_thread_flag(TIF_SYSCALL_TRACE) | ||
| 309 | && (current->ptrace & PT_PTRACED)) | ||
| 310 | do_syscall_trace(); | ||
| 311 | |||
| 307 | if (unlikely(current->audit_context)) | 312 | if (unlikely(current->audit_context)) |
| 308 | audit_syscall_entry(current, regs->gpr[0], | 313 | audit_syscall_entry(current, |
| 314 | test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64, | ||
| 315 | regs->gpr[0], | ||
| 309 | regs->gpr[3], regs->gpr[4], | 316 | regs->gpr[3], regs->gpr[4], |
| 310 | regs->gpr[5], regs->gpr[6]); | 317 | regs->gpr[5], regs->gpr[6]); |
| 311 | 318 | ||
| 312 | if (test_thread_flag(TIF_SYSCALL_TRACE) | ||
| 313 | && (current->ptrace & PT_PTRACED)) | ||
| 314 | do_syscall_trace(); | ||
| 315 | } | 319 | } |
| 316 | 320 | ||
| 317 | void do_syscall_trace_leave(struct pt_regs *regs) | 321 | void do_syscall_trace_leave(struct pt_regs *regs) |
| @@ -319,7 +323,9 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
| 319 | secure_computing(regs->gpr[0]); | 323 | secure_computing(regs->gpr[0]); |
| 320 | 324 | ||
| 321 | if (unlikely(current->audit_context)) | 325 | if (unlikely(current->audit_context)) |
| 322 | audit_syscall_exit(current, regs->result); | 326 | audit_syscall_exit(current, |
| 327 | (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, | ||
| 328 | regs->result); | ||
| 323 | 329 | ||
| 324 | if ((test_thread_flag(TIF_SYSCALL_TRACE) | 330 | if ((test_thread_flag(TIF_SYSCALL_TRACE) |
| 325 | || test_thread_flag(TIF_SINGLESTEP)) | 331 | || test_thread_flag(TIF_SINGLESTEP)) |
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c index ee81b1b776cc..16436426c7e2 100644 --- a/arch/ppc64/kernel/ptrace32.c +++ b/arch/ppc64/kernel/ptrace32.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/ptrace.h> | 26 | #include <linux/ptrace.h> |
| 27 | #include <linux/user.h> | 27 | #include <linux/user.h> |
| 28 | #include <linux/security.h> | 28 | #include <linux/security.h> |
| 29 | #include <linux/signal.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
| 31 | #include <asm/page.h> | 32 | #include <asm/page.h> |
| @@ -293,7 +294,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) | |||
| 293 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 294 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
| 294 | case PTRACE_CONT: { /* restart after signal. */ | 295 | case PTRACE_CONT: { /* restart after signal. */ |
| 295 | ret = -EIO; | 296 | ret = -EIO; |
| 296 | if ((unsigned long) data > _NSIG) | 297 | if (!valid_signal(data)) |
| 297 | break; | 298 | break; |
| 298 | if (request == PTRACE_SYSCALL) | 299 | if (request == PTRACE_SYSCALL) |
| 299 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 300 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
| @@ -325,7 +326,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) | |||
| 325 | 326 | ||
| 326 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ | 327 | case PTRACE_SINGLESTEP: { /* set the trap flag. */ |
| 327 | ret = -EIO; | 328 | ret = -EIO; |
| 328 | if ((unsigned long) data > _NSIG) | 329 | if (!valid_signal(data)) |
| 329 | break; | 330 | break; |
| 330 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 331 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
| 331 | set_single_step(child); | 332 | set_single_step(child); |
diff --git a/arch/ppc64/kernel/rtas_flash.c b/arch/ppc64/kernel/rtas_flash.c index 3213837282ca..923e2e201a70 100644 --- a/arch/ppc64/kernel/rtas_flash.c +++ b/arch/ppc64/kernel/rtas_flash.c | |||
| @@ -218,7 +218,7 @@ static void get_flash_status_msg(int status, char *buf) | |||
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | /* Reading the proc file will show status (not the firmware contents) */ | 220 | /* Reading the proc file will show status (not the firmware contents) */ |
| 221 | static ssize_t rtas_flash_read(struct file *file, char *buf, | 221 | static ssize_t rtas_flash_read(struct file *file, char __user *buf, |
| 222 | size_t count, loff_t *ppos) | 222 | size_t count, loff_t *ppos) |
| 223 | { | 223 | { |
| 224 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); | 224 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); |
| @@ -256,7 +256,7 @@ static ssize_t rtas_flash_read(struct file *file, char *buf, | |||
| 256 | * count is. If the system is low on memory it will be just as well | 256 | * count is. If the system is low on memory it will be just as well |
| 257 | * that we fail.... | 257 | * that we fail.... |
| 258 | */ | 258 | */ |
| 259 | static ssize_t rtas_flash_write(struct file *file, const char *buffer, | 259 | static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, |
| 260 | size_t count, loff_t *off) | 260 | size_t count, loff_t *off) |
| 261 | { | 261 | { |
| 262 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); | 262 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); |
| @@ -356,7 +356,7 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf) | |||
| 356 | args_buf->status = rc; | 356 | args_buf->status = rc; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | static ssize_t manage_flash_read(struct file *file, char *buf, | 359 | static ssize_t manage_flash_read(struct file *file, char __user *buf, |
| 360 | size_t count, loff_t *ppos) | 360 | size_t count, loff_t *ppos) |
| 361 | { | 361 | { |
| 362 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); | 362 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); |
| @@ -386,7 +386,7 @@ static ssize_t manage_flash_read(struct file *file, char *buf, | |||
| 386 | return msglen; | 386 | return msglen; |
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | static ssize_t manage_flash_write(struct file *file, const char *buf, | 389 | static ssize_t manage_flash_write(struct file *file, const char __user *buf, |
| 390 | size_t count, loff_t *off) | 390 | size_t count, loff_t *off) |
| 391 | { | 391 | { |
| 392 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); | 392 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); |
| @@ -466,7 +466,7 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, | |||
| 466 | return n; | 466 | return n; |
| 467 | } | 467 | } |
| 468 | 468 | ||
| 469 | static ssize_t validate_flash_read(struct file *file, char *buf, | 469 | static ssize_t validate_flash_read(struct file *file, char __user *buf, |
| 470 | size_t count, loff_t *ppos) | 470 | size_t count, loff_t *ppos) |
| 471 | { | 471 | { |
| 472 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); | 472 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); |
| @@ -494,7 +494,7 @@ static ssize_t validate_flash_read(struct file *file, char *buf, | |||
| 494 | return msglen; | 494 | return msglen; |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | static ssize_t validate_flash_write(struct file *file, const char *buf, | 497 | static ssize_t validate_flash_write(struct file *file, const char __user *buf, |
| 498 | size_t count, loff_t *off) | 498 | size_t count, loff_t *off) |
| 499 | { | 499 | { |
| 500 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); | 500 | struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); |
diff --git a/arch/ppc64/kernel/scanlog.c b/arch/ppc64/kernel/scanlog.c index 189b81a41987..4d70736619c7 100644 --- a/arch/ppc64/kernel/scanlog.c +++ b/arch/ppc64/kernel/scanlog.c | |||
| @@ -43,7 +43,7 @@ static int scanlog_debug; | |||
| 43 | static unsigned int ibm_scan_log_dump; /* RTAS token */ | 43 | static unsigned int ibm_scan_log_dump; /* RTAS token */ |
| 44 | static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ | 44 | static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ |
| 45 | 45 | ||
| 46 | static ssize_t scanlog_read(struct file *file, char *buf, | 46 | static ssize_t scanlog_read(struct file *file, char __user *buf, |
| 47 | size_t count, loff_t *ppos) | 47 | size_t count, loff_t *ppos) |
| 48 | { | 48 | { |
| 49 | struct inode * inode = file->f_dentry->d_inode; | 49 | struct inode * inode = file->f_dentry->d_inode; |
| @@ -129,7 +129,7 @@ static ssize_t scanlog_read(struct file *file, char *buf, | |||
| 129 | /*NOTREACHED*/ | 129 | /*NOTREACHED*/ |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static ssize_t scanlog_write(struct file * file, const char * buf, | 132 | static ssize_t scanlog_write(struct file * file, const char __user * buf, |
| 133 | size_t count, loff_t *ppos) | 133 | size_t count, loff_t *ppos) |
| 134 | { | 134 | { |
| 135 | char stkbuf[20]; | 135 | char stkbuf[20]; |
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index a95a2b49a1d5..bf782276984c 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c | |||
| @@ -42,11 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
| 44 | 44 | ||
| 45 | #ifndef MIN | 45 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) |
| 46 | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | ||
| 47 | #endif | ||
| 48 | |||
| 49 | #define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs)) | ||
| 50 | #define FP_REGS_SIZE sizeof(elf_fpregset_t) | 46 | #define FP_REGS_SIZE sizeof(elf_fpregset_t) |
| 51 | 47 | ||
| 52 | #define TRAMP_TRACEBACK 3 | 48 | #define TRAMP_TRACEBACK 3 |
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c index b0e167db6af9..3c2fa5c284c0 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/ppc64/kernel/signal32.c | |||
| @@ -657,7 +657,7 @@ static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
| 657 | 657 | ||
| 658 | /* Save user registers on the stack */ | 658 | /* Save user registers on the stack */ |
| 659 | frame = &rt_sf->uc.uc_mcontext; | 659 | frame = &rt_sf->uc.uc_mcontext; |
| 660 | if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) | 660 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
| 661 | goto badframe; | 661 | goto badframe; |
| 662 | 662 | ||
| 663 | if (vdso32_rt_sigtramp && current->thread.vdso_base) { | 663 | if (vdso32_rt_sigtramp && current->thread.vdso_base) { |
| @@ -842,7 +842,7 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
| 842 | regs->link = (unsigned long) frame->mctx.tramp; | 842 | regs->link = (unsigned long) frame->mctx.tramp; |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) | 845 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
| 846 | goto badframe; | 846 | goto badframe; |
| 847 | regs->gpr[1] = (unsigned long) newsp; | 847 | regs->gpr[1] = (unsigned long) newsp; |
| 848 | regs->gpr[3] = sig; | 848 | regs->gpr[3] = sig; |
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 1c92da3e4525..3b906cd94037 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c | |||
| @@ -125,7 +125,7 @@ void __devinit smp_generic_kick_cpu(int nr) | |||
| 125 | * the processor will continue on to secondary_start | 125 | * the processor will continue on to secondary_start |
| 126 | */ | 126 | */ |
| 127 | paca[nr].cpu_start = 1; | 127 | paca[nr].cpu_start = 1; |
| 128 | mb(); | 128 | smp_mb(); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 131 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
| @@ -256,7 +256,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | |||
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | call_data = &data; | 258 | call_data = &data; |
| 259 | wmb(); | 259 | smp_wmb(); |
| 260 | /* Send a message to all other CPUs and wait for them to respond */ | 260 | /* Send a message to all other CPUs and wait for them to respond */ |
| 261 | smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); | 261 | smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); |
| 262 | 262 | ||
| @@ -431,7 +431,7 @@ int generic_cpu_enable(unsigned int cpu) | |||
| 431 | 431 | ||
| 432 | /* get the target out of it's holding state */ | 432 | /* get the target out of it's holding state */ |
| 433 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | 433 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; |
| 434 | wmb(); | 434 | smp_wmb(); |
| 435 | 435 | ||
| 436 | while (!cpu_online(cpu)) | 436 | while (!cpu_online(cpu)) |
| 437 | cpu_relax(); | 437 | cpu_relax(); |
| @@ -447,7 +447,7 @@ void generic_cpu_die(unsigned int cpu) | |||
| 447 | int i; | 447 | int i; |
| 448 | 448 | ||
| 449 | for (i = 0; i < 100; i++) { | 449 | for (i = 0; i < 100; i++) { |
| 450 | rmb(); | 450 | smp_rmb(); |
| 451 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) | 451 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) |
| 452 | return; | 452 | return; |
| 453 | msleep(100); | 453 | msleep(100); |
| @@ -463,7 +463,7 @@ void generic_mach_cpu_die(void) | |||
| 463 | cpu = smp_processor_id(); | 463 | cpu = smp_processor_id(); |
| 464 | printk(KERN_DEBUG "CPU%d offline\n", cpu); | 464 | printk(KERN_DEBUG "CPU%d offline\n", cpu); |
| 465 | __get_cpu_var(cpu_state) = CPU_DEAD; | 465 | __get_cpu_var(cpu_state) = CPU_DEAD; |
| 466 | wmb(); | 466 | smp_wmb(); |
| 467 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) | 467 | while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) |
| 468 | cpu_relax(); | 468 | cpu_relax(); |
| 469 | 469 | ||
| @@ -515,7 +515,7 @@ int __devinit __cpu_up(unsigned int cpu) | |||
| 515 | * be written out to main store before we release | 515 | * be written out to main store before we release |
| 516 | * the processor. | 516 | * the processor. |
| 517 | */ | 517 | */ |
| 518 | mb(); | 518 | smp_mb(); |
| 519 | 519 | ||
| 520 | /* wake up cpus */ | 520 | /* wake up cpus */ |
| 521 | DBG("smp: kicking cpu %d\n", cpu); | 521 | DBG("smp: kicking cpu %d\n", cpu); |
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 77ded5a363b6..772a465b49f9 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c | |||
| @@ -221,15 +221,15 @@ static __inline__ void timer_recalc_offset(unsigned long cur_tb) | |||
| 221 | temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs; | 221 | temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs; |
| 222 | temp_varp->tb_orig_stamp = new_tb_orig_stamp; | 222 | temp_varp->tb_orig_stamp = new_tb_orig_stamp; |
| 223 | temp_varp->stamp_xsec = new_stamp_xsec; | 223 | temp_varp->stamp_xsec = new_stamp_xsec; |
| 224 | mb(); | 224 | smp_mb(); |
| 225 | do_gtod.varp = temp_varp; | 225 | do_gtod.varp = temp_varp; |
| 226 | do_gtod.var_idx = temp_idx; | 226 | do_gtod.var_idx = temp_idx; |
| 227 | 227 | ||
| 228 | ++(systemcfg->tb_update_count); | 228 | ++(systemcfg->tb_update_count); |
| 229 | wmb(); | 229 | smp_wmb(); |
| 230 | systemcfg->tb_orig_stamp = new_tb_orig_stamp; | 230 | systemcfg->tb_orig_stamp = new_tb_orig_stamp; |
| 231 | systemcfg->stamp_xsec = new_stamp_xsec; | 231 | systemcfg->stamp_xsec = new_stamp_xsec; |
| 232 | wmb(); | 232 | smp_wmb(); |
| 233 | ++(systemcfg->tb_update_count); | 233 | ++(systemcfg->tb_update_count); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| @@ -648,7 +648,7 @@ void ppc_adjtimex(void) | |||
| 648 | temp_varp->tb_to_xs = new_tb_to_xs; | 648 | temp_varp->tb_to_xs = new_tb_to_xs; |
| 649 | temp_varp->stamp_xsec = new_stamp_xsec; | 649 | temp_varp->stamp_xsec = new_stamp_xsec; |
| 650 | temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp; | 650 | temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp; |
| 651 | mb(); | 651 | smp_mb(); |
| 652 | do_gtod.varp = temp_varp; | 652 | do_gtod.varp = temp_varp; |
| 653 | do_gtod.var_idx = temp_idx; | 653 | do_gtod.var_idx = temp_idx; |
| 654 | 654 | ||
| @@ -662,10 +662,10 @@ void ppc_adjtimex(void) | |||
| 662 | * loops back and reads them again until this criteria is met. | 662 | * loops back and reads them again until this criteria is met. |
| 663 | */ | 663 | */ |
| 664 | ++(systemcfg->tb_update_count); | 664 | ++(systemcfg->tb_update_count); |
| 665 | wmb(); | 665 | smp_wmb(); |
| 666 | systemcfg->tb_to_xs = new_tb_to_xs; | 666 | systemcfg->tb_to_xs = new_tb_to_xs; |
| 667 | systemcfg->stamp_xsec = new_stamp_xsec; | 667 | systemcfg->stamp_xsec = new_stamp_xsec; |
| 668 | wmb(); | 668 | smp_wmb(); |
| 669 | ++(systemcfg->tb_update_count); | 669 | ++(systemcfg->tb_update_count); |
| 670 | 670 | ||
| 671 | write_sequnlock_irqrestore( &xtime_lock, flags ); | 671 | write_sequnlock_irqrestore( &xtime_lock, flags ); |
diff --git a/arch/ppc64/kernel/vdso32/Makefile b/arch/ppc64/kernel/vdso32/Makefile index ede2f7e477c2..0b1b0df973eb 100644 --- a/arch/ppc64/kernel/vdso32/Makefile +++ b/arch/ppc64/kernel/vdso32/Makefile | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | 1 | ||
| 2 | # List of files in the vdso, has to be asm only for now | 2 | # List of files in the vdso, has to be asm only for now |
| 3 | 3 | ||
| 4 | obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o | 4 | obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o |
| 5 | 5 | ||
| 6 | # Build rules | 6 | # Build rules |
| 7 | 7 | ||
diff --git a/arch/ppc64/kernel/vdso32/cacheflush.S b/arch/ppc64/kernel/vdso32/cacheflush.S index c74fddb6afd4..0ed7ea721715 100644 --- a/arch/ppc64/kernel/vdso32/cacheflush.S +++ b/arch/ppc64/kernel/vdso32/cacheflush.S | |||
| @@ -47,6 +47,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
| 47 | addi r6,r6,128 | 47 | addi r6,r6,128 |
| 48 | bdnz 1b | 48 | bdnz 1b |
| 49 | isync | 49 | isync |
| 50 | li r3,0 | ||
| 50 | blr | 51 | blr |
| 51 | .cfi_endproc | 52 | .cfi_endproc |
| 52 | V_FUNCTION_END(__kernel_sync_dicache) | 53 | V_FUNCTION_END(__kernel_sync_dicache) |
| @@ -59,6 +60,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | |||
| 59 | .cfi_startproc | 60 | .cfi_startproc |
| 60 | sync | 61 | sync |
| 61 | isync | 62 | isync |
| 63 | li r3,0 | ||
| 62 | blr | 64 | blr |
| 63 | .cfi_endproc | 65 | .cfi_endproc |
| 64 | V_FUNCTION_END(__kernel_sync_dicache_p5) | 66 | V_FUNCTION_END(__kernel_sync_dicache_p5) |
diff --git a/arch/ppc64/kernel/vdso32/gettimeofday.S b/arch/ppc64/kernel/vdso32/gettimeofday.S index ca7f415195c4..2b48bf1fb109 100644 --- a/arch/ppc64/kernel/vdso32/gettimeofday.S +++ b/arch/ppc64/kernel/vdso32/gettimeofday.S | |||
| @@ -58,6 +58,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
| 58 | stw r5,TZONE_TZ_DSTTIME(r11) | 58 | stw r5,TZONE_TZ_DSTTIME(r11) |
| 59 | 59 | ||
| 60 | 1: mtlr r12 | 60 | 1: mtlr r12 |
| 61 | li r3,0 | ||
| 61 | blr | 62 | blr |
| 62 | 63 | ||
| 63 | 2: mr r3,r10 | 64 | 2: mr r3,r10 |
diff --git a/arch/ppc64/kernel/vdso32/note.S b/arch/ppc64/kernel/vdso32/note.S new file mode 100644 index 000000000000..d4b5be4f3d5f --- /dev/null +++ b/arch/ppc64/kernel/vdso32/note.S | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. | ||
| 3 | * Here we can supply some information useful to userland. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/uts.h> | ||
| 7 | #include <linux/version.h> | ||
| 8 | |||
| 9 | #define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type) \ | ||
| 10 | .section name, flags; \ | ||
| 11 | .balign 4; \ | ||
| 12 | .long 1f - 0f; /* name length */ \ | ||
| 13 | .long 3f - 2f; /* data length */ \ | ||
| 14 | .long type; /* note type */ \ | ||
| 15 | 0: .asciz vendor; /* vendor name */ \ | ||
| 16 | 1: .balign 4; \ | ||
| 17 | 2: | ||
| 18 | |||
| 19 | #define ASM_ELF_NOTE_END \ | ||
| 20 | 3: .balign 4; /* pad out section */ \ | ||
| 21 | .previous | ||
| 22 | |||
| 23 | ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0) | ||
| 24 | .long LINUX_VERSION_CODE | ||
| 25 | ASM_ELF_NOTE_END | ||
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S index cca27bd03a57..11290c902ba3 100644 --- a/arch/ppc64/kernel/vdso32/vdso32.lds.S +++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S | |||
| @@ -20,6 +20,8 @@ SECTIONS | |||
| 20 | .gnu.version_d : { *(.gnu.version_d) } | 20 | .gnu.version_d : { *(.gnu.version_d) } |
| 21 | .gnu.version_r : { *(.gnu.version_r) } | 21 | .gnu.version_r : { *(.gnu.version_r) } |
| 22 | 22 | ||
| 23 | .note : { *(.note.*) } :text :note | ||
| 24 | |||
| 23 | . = ALIGN (16); | 25 | . = ALIGN (16); |
| 24 | .text : | 26 | .text : |
| 25 | { | 27 | { |
| @@ -87,6 +89,7 @@ SECTIONS | |||
| 87 | PHDRS | 89 | PHDRS |
| 88 | { | 90 | { |
| 89 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ | 91 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ |
| 92 | note PT_NOTE FLAGS(4); /* PF_R */ | ||
| 90 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 93 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
| 91 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ | 94 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ |
| 92 | } | 95 | } |
diff --git a/arch/ppc64/kernel/vdso64/Makefile b/arch/ppc64/kernel/vdso64/Makefile index bd3f70b1a384..ab39988452cc 100644 --- a/arch/ppc64/kernel/vdso64/Makefile +++ b/arch/ppc64/kernel/vdso64/Makefile | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | # List of files in the vdso, has to be asm only for now | 1 | # List of files in the vdso, has to be asm only for now |
| 2 | 2 | ||
| 3 | obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o | 3 | obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o |
| 4 | 4 | ||
| 5 | # Build rules | 5 | # Build rules |
| 6 | 6 | ||
diff --git a/arch/ppc64/kernel/vdso64/cacheflush.S b/arch/ppc64/kernel/vdso64/cacheflush.S index d9696ffcf334..e0725b7b7003 100644 --- a/arch/ppc64/kernel/vdso64/cacheflush.S +++ b/arch/ppc64/kernel/vdso64/cacheflush.S | |||
| @@ -47,6 +47,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
| 47 | addi r6,r6,128 | 47 | addi r6,r6,128 |
| 48 | bdnz 1b | 48 | bdnz 1b |
| 49 | isync | 49 | isync |
| 50 | li r3,0 | ||
| 50 | blr | 51 | blr |
| 51 | .cfi_endproc | 52 | .cfi_endproc |
| 52 | V_FUNCTION_END(__kernel_sync_dicache) | 53 | V_FUNCTION_END(__kernel_sync_dicache) |
| @@ -59,6 +60,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | |||
| 59 | .cfi_startproc | 60 | .cfi_startproc |
| 60 | sync | 61 | sync |
| 61 | isync | 62 | isync |
| 63 | li r3,0 | ||
| 62 | blr | 64 | blr |
| 63 | .cfi_endproc | 65 | .cfi_endproc |
| 64 | V_FUNCTION_END(__kernel_sync_dicache_p5) | 66 | V_FUNCTION_END(__kernel_sync_dicache_p5) |
diff --git a/arch/ppc64/kernel/vdso64/note.S b/arch/ppc64/kernel/vdso64/note.S new file mode 100644 index 000000000000..dc2a509f7e8a --- /dev/null +++ b/arch/ppc64/kernel/vdso64/note.S | |||
| @@ -0,0 +1 @@ | |||
| #include "../vdso32/note.S" | |||
diff --git a/arch/ppc64/kernel/vdso64/vdso64.lds.S b/arch/ppc64/kernel/vdso64/vdso64.lds.S index 942c815c7bc7..9cb28181da80 100644 --- a/arch/ppc64/kernel/vdso64/vdso64.lds.S +++ b/arch/ppc64/kernel/vdso64/vdso64.lds.S | |||
| @@ -18,12 +18,14 @@ SECTIONS | |||
| 18 | .gnu.version_d : { *(.gnu.version_d) } | 18 | .gnu.version_d : { *(.gnu.version_d) } |
| 19 | .gnu.version_r : { *(.gnu.version_r) } | 19 | .gnu.version_r : { *(.gnu.version_r) } |
| 20 | 20 | ||
| 21 | .note : { *(.note.*) } :text :note | ||
| 22 | |||
| 21 | . = ALIGN (16); | 23 | . = ALIGN (16); |
| 22 | .text : | 24 | .text : |
| 23 | { | 25 | { |
| 24 | *(.text .stub .text.* .gnu.linkonce.t.*) | 26 | *(.text .stub .text.* .gnu.linkonce.t.*) |
| 25 | *(.sfpr .glink) | 27 | *(.sfpr .glink) |
| 26 | } | 28 | } :text |
| 27 | PROVIDE (__etext = .); | 29 | PROVIDE (__etext = .); |
| 28 | PROVIDE (_etext = .); | 30 | PROVIDE (_etext = .); |
| 29 | PROVIDE (etext = .); | 31 | PROVIDE (etext = .); |
| @@ -88,6 +90,7 @@ SECTIONS | |||
| 88 | PHDRS | 90 | PHDRS |
| 89 | { | 91 | { |
| 90 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ | 92 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ |
| 93 | note PT_NOTE FLAGS(4); /* PF_R */ | ||
| 91 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 94 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
| 92 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ | 95 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ |
| 93 | } | 96 | } |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index eedd1d3c2a10..879f39b90a33 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
| @@ -432,6 +432,7 @@ void xics_cause_IPI(int cpu) | |||
| 432 | { | 432 | { |
| 433 | ops->qirr_info(cpu, IPI_PRIORITY); | 433 | ops->qirr_info(cpu, IPI_PRIORITY); |
| 434 | } | 434 | } |
| 435 | #endif /* CONFIG_SMP */ | ||
| 435 | 436 | ||
| 436 | void xics_setup_cpu(void) | 437 | void xics_setup_cpu(void) |
| 437 | { | 438 | { |
| @@ -439,9 +440,17 @@ void xics_setup_cpu(void) | |||
| 439 | 440 | ||
| 440 | ops->cppr_info(cpu, 0xff); | 441 | ops->cppr_info(cpu, 0xff); |
| 441 | iosync(); | 442 | iosync(); |
| 442 | } | ||
| 443 | 443 | ||
| 444 | #endif /* CONFIG_SMP */ | 444 | /* |
| 445 | * Put the calling processor into the GIQ. This is really only | ||
| 446 | * necessary from a secondary thread as the OF start-cpu interface | ||
| 447 | * performs this function for us on primary threads. | ||
| 448 | * | ||
| 449 | * XXX: undo of teardown on kexec needs this too, as may hotplug | ||
| 450 | */ | ||
| 451 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
| 452 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); | ||
| 453 | } | ||
| 445 | 454 | ||
| 446 | void xics_init_IRQ(void) | 455 | void xics_init_IRQ(void) |
| 447 | { | 456 | { |
| @@ -563,8 +572,7 @@ nextnode: | |||
| 563 | for (; i < NR_IRQS; ++i) | 572 | for (; i < NR_IRQS; ++i) |
| 564 | get_irq_desc(i)->handler = &xics_pic; | 573 | get_irq_desc(i)->handler = &xics_pic; |
| 565 | 574 | ||
| 566 | ops->cppr_info(boot_cpuid, 0xff); | 575 | xics_setup_cpu(); |
| 567 | iosync(); | ||
| 568 | 576 | ||
| 569 | ppc64_boot_msg(0x21, "XICS Done"); | 577 | ppc64_boot_msg(0x21, "XICS Done"); |
| 570 | } | 578 | } |
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S index 8c0156a37001..c23d46956dd9 100644 --- a/arch/ppc64/mm/hash_low.S +++ b/arch/ppc64/mm/hash_low.S | |||
| @@ -85,7 +85,10 @@ _GLOBAL(__hash_page) | |||
| 85 | bne- htab_wrong_access | 85 | bne- htab_wrong_access |
| 86 | /* Check if PTE is busy */ | 86 | /* Check if PTE is busy */ |
| 87 | andi. r0,r31,_PAGE_BUSY | 87 | andi. r0,r31,_PAGE_BUSY |
| 88 | bne- 1b | 88 | /* If so, just bail out and refault if needed. Someone else |
| 89 | * is changing this PTE anyway and might hash it. | ||
| 90 | */ | ||
| 91 | bne- bail_ok | ||
| 89 | /* Prepare new PTE value (turn access RW into DIRTY, then | 92 | /* Prepare new PTE value (turn access RW into DIRTY, then |
| 90 | * add BUSY,HASHPTE and ACCESSED) | 93 | * add BUSY,HASHPTE and ACCESSED) |
| 91 | */ | 94 | */ |
| @@ -215,6 +218,10 @@ _GLOBAL(htab_call_hpte_remove) | |||
| 215 | /* Try all again */ | 218 | /* Try all again */ |
| 216 | b htab_insert_pte | 219 | b htab_insert_pte |
| 217 | 220 | ||
| 221 | bail_ok: | ||
| 222 | li r3,0 | ||
| 223 | b bail | ||
| 224 | |||
| 218 | htab_pte_insert_ok: | 225 | htab_pte_insert_ok: |
| 219 | /* Insert slot number & secondary bit in PTE */ | 226 | /* Insert slot number & secondary bit in PTE */ |
| 220 | rldimi r30,r3,12,63-15 | 227 | rldimi r30,r3,12,63-15 |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 144657e0c3d5..52b6b9305341 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c | |||
| @@ -320,8 +320,7 @@ static void native_flush_hash_range(unsigned long context, | |||
| 320 | 320 | ||
| 321 | j = 0; | 321 | j = 0; |
| 322 | for (i = 0; i < number; i++) { | 322 | for (i = 0; i < number; i++) { |
| 323 | if ((batch->addr[i] >= USER_START) && | 323 | if (batch->addr[i] < KERNELBASE) |
| 324 | (batch->addr[i] <= USER_END)) | ||
| 325 | vsid = get_vsid(context, batch->addr[i]); | 324 | vsid = get_vsid(context, batch->addr[i]); |
| 326 | else | 325 | else |
| 327 | vsid = get_kernel_vsid(batch->addr[i]); | 326 | vsid = get_kernel_vsid(batch->addr[i]); |
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index e48be12f518c..0a0f97008d02 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c | |||
| @@ -298,24 +298,23 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
| 298 | int local = 0; | 298 | int local = 0; |
| 299 | cpumask_t tmp; | 299 | cpumask_t tmp; |
| 300 | 300 | ||
| 301 | if ((ea & ~REGION_MASK) > EADDR_MASK) | ||
| 302 | return 1; | ||
| 303 | |||
| 301 | switch (REGION_ID(ea)) { | 304 | switch (REGION_ID(ea)) { |
| 302 | case USER_REGION_ID: | 305 | case USER_REGION_ID: |
| 303 | user_region = 1; | 306 | user_region = 1; |
| 304 | mm = current->mm; | 307 | mm = current->mm; |
| 305 | if ((ea > USER_END) || (! mm)) | 308 | if (! mm) |
| 306 | return 1; | 309 | return 1; |
| 307 | 310 | ||
| 308 | vsid = get_vsid(mm->context.id, ea); | 311 | vsid = get_vsid(mm->context.id, ea); |
| 309 | break; | 312 | break; |
| 310 | case IO_REGION_ID: | 313 | case IO_REGION_ID: |
| 311 | if (ea > IMALLOC_END) | ||
| 312 | return 1; | ||
| 313 | mm = &ioremap_mm; | 314 | mm = &ioremap_mm; |
| 314 | vsid = get_kernel_vsid(ea); | 315 | vsid = get_kernel_vsid(ea); |
| 315 | break; | 316 | break; |
| 316 | case VMALLOC_REGION_ID: | 317 | case VMALLOC_REGION_ID: |
| 317 | if (ea > VMALLOC_END) | ||
| 318 | return 1; | ||
| 319 | mm = &init_mm; | 318 | mm = &init_mm; |
| 320 | vsid = get_kernel_vsid(ea); | 319 | vsid = get_kernel_vsid(ea); |
| 321 | break; | 320 | break; |
| @@ -362,7 +361,7 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, | |||
| 362 | unsigned long vsid, vpn, va, hash, secondary, slot; | 361 | unsigned long vsid, vpn, va, hash, secondary, slot; |
| 363 | unsigned long huge = pte_huge(pte); | 362 | unsigned long huge = pte_huge(pte); |
| 364 | 363 | ||
| 365 | if ((ea >= USER_START) && (ea <= USER_END)) | 364 | if (ea < KERNELBASE) |
| 366 | vsid = get_vsid(context, ea); | 365 | vsid = get_vsid(context, ea); |
| 367 | else | 366 | else |
| 368 | vsid = get_kernel_vsid(ea); | 367 | vsid = get_kernel_vsid(ea); |
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index 390296efe3e0..d3bf86a5c1ad 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c | |||
| @@ -42,7 +42,7 @@ static inline int hugepgd_index(unsigned long addr) | |||
| 42 | return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT; | 42 | return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) | 45 | static pud_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) |
| 46 | { | 46 | { |
| 47 | int index; | 47 | int index; |
| 48 | 48 | ||
| @@ -52,21 +52,21 @@ static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) | |||
| 52 | 52 | ||
| 53 | index = hugepgd_index(addr); | 53 | index = hugepgd_index(addr); |
| 54 | BUG_ON(index >= PTRS_PER_HUGEPGD); | 54 | BUG_ON(index >= PTRS_PER_HUGEPGD); |
| 55 | return mm->context.huge_pgdir + index; | 55 | return (pud_t *)(mm->context.huge_pgdir + index); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static inline pte_t *hugepte_offset(pgd_t *dir, unsigned long addr) | 58 | static inline pte_t *hugepte_offset(pud_t *dir, unsigned long addr) |
| 59 | { | 59 | { |
| 60 | int index; | 60 | int index; |
| 61 | 61 | ||
| 62 | if (pgd_none(*dir)) | 62 | if (pud_none(*dir)) |
| 63 | return NULL; | 63 | return NULL; |
| 64 | 64 | ||
| 65 | index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE; | 65 | index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE; |
| 66 | return (pte_t *)pgd_page(*dir) + index; | 66 | return (pte_t *)pud_page(*dir) + index; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) | 69 | static pud_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) |
| 70 | { | 70 | { |
| 71 | BUG_ON(! in_hugepage_area(mm->context, addr)); | 71 | BUG_ON(! in_hugepage_area(mm->context, addr)); |
| 72 | 72 | ||
| @@ -90,10 +90,9 @@ static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) | |||
| 90 | return hugepgd_offset(mm, addr); | 90 | return hugepgd_offset(mm, addr); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | 93 | static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr) |
| 94 | unsigned long addr) | ||
| 95 | { | 94 | { |
| 96 | if (! pgd_present(*dir)) { | 95 | if (! pud_present(*dir)) { |
| 97 | pte_t *new; | 96 | pte_t *new; |
| 98 | 97 | ||
| 99 | spin_unlock(&mm->page_table_lock); | 98 | spin_unlock(&mm->page_table_lock); |
| @@ -104,7 +103,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | |||
| 104 | * Because we dropped the lock, we should re-check the | 103 | * Because we dropped the lock, we should re-check the |
| 105 | * entry, as somebody else could have populated it.. | 104 | * entry, as somebody else could have populated it.. |
| 106 | */ | 105 | */ |
| 107 | if (pgd_present(*dir)) { | 106 | if (pud_present(*dir)) { |
| 108 | if (new) | 107 | if (new) |
| 109 | kmem_cache_free(zero_cache, new); | 108 | kmem_cache_free(zero_cache, new); |
| 110 | } else { | 109 | } else { |
| @@ -115,7 +114,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | |||
| 115 | ptepage = virt_to_page(new); | 114 | ptepage = virt_to_page(new); |
| 116 | ptepage->mapping = (void *) mm; | 115 | ptepage->mapping = (void *) mm; |
| 117 | ptepage->index = addr & HUGEPGDIR_MASK; | 116 | ptepage->index = addr & HUGEPGDIR_MASK; |
| 118 | pgd_populate(mm, dir, new); | 117 | pud_populate(mm, dir, new); |
| 119 | } | 118 | } |
| 120 | } | 119 | } |
| 121 | 120 | ||
| @@ -124,28 +123,28 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | |||
| 124 | 123 | ||
| 125 | static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | 124 | static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) |
| 126 | { | 125 | { |
| 127 | pgd_t *pgd; | 126 | pud_t *pud; |
| 128 | 127 | ||
| 129 | BUG_ON(! in_hugepage_area(mm->context, addr)); | 128 | BUG_ON(! in_hugepage_area(mm->context, addr)); |
| 130 | 129 | ||
| 131 | pgd = hugepgd_offset(mm, addr); | 130 | pud = hugepgd_offset(mm, addr); |
| 132 | if (! pgd) | 131 | if (! pud) |
| 133 | return NULL; | 132 | return NULL; |
| 134 | 133 | ||
| 135 | return hugepte_offset(pgd, addr); | 134 | return hugepte_offset(pud, addr); |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) | 137 | static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) |
| 139 | { | 138 | { |
| 140 | pgd_t *pgd; | 139 | pud_t *pud; |
| 141 | 140 | ||
| 142 | BUG_ON(! in_hugepage_area(mm->context, addr)); | 141 | BUG_ON(! in_hugepage_area(mm->context, addr)); |
| 143 | 142 | ||
| 144 | pgd = hugepgd_alloc(mm, addr); | 143 | pud = hugepgd_alloc(mm, addr); |
| 145 | if (! pgd) | 144 | if (! pud) |
| 146 | return NULL; | 145 | return NULL; |
| 147 | 146 | ||
| 148 | return hugepte_alloc(mm, pgd, addr); | 147 | return hugepte_alloc(mm, pud, addr); |
| 149 | } | 148 | } |
| 150 | 149 | ||
| 151 | static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, | 150 | static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, |
| @@ -709,10 +708,10 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm) | |||
| 709 | 708 | ||
| 710 | /* cleanup any hugepte pages leftover */ | 709 | /* cleanup any hugepte pages leftover */ |
| 711 | for (i = 0; i < PTRS_PER_HUGEPGD; i++) { | 710 | for (i = 0; i < PTRS_PER_HUGEPGD; i++) { |
| 712 | pgd_t *pgd = pgdir + i; | 711 | pud_t *pud = (pud_t *)(pgdir + i); |
| 713 | 712 | ||
| 714 | if (! pgd_none(*pgd)) { | 713 | if (! pud_none(*pud)) { |
| 715 | pte_t *pte = (pte_t *)pgd_page(*pgd); | 714 | pte_t *pte = (pte_t *)pud_page(*pud); |
| 716 | struct page *ptepage = virt_to_page(pte); | 715 | struct page *ptepage = virt_to_page(pte); |
| 717 | 716 | ||
| 718 | ptepage->mapping = NULL; | 717 | ptepage->mapping = NULL; |
| @@ -720,7 +719,7 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm) | |||
| 720 | BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE)); | 719 | BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE)); |
| 721 | kmem_cache_free(zero_cache, pte); | 720 | kmem_cache_free(zero_cache, pte); |
| 722 | } | 721 | } |
| 723 | pgd_clear(pgd); | 722 | pud_clear(pud); |
| 724 | } | 723 | } |
| 725 | 724 | ||
| 726 | BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE)); | 725 | BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE)); |
diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c index 9d92b0d9cde5..cb8727f3267a 100644 --- a/arch/ppc64/mm/imalloc.c +++ b/arch/ppc64/mm/imalloc.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <asm/pgalloc.h> | 14 | #include <asm/pgalloc.h> |
| 15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
| 16 | #include <asm/semaphore.h> | 16 | #include <asm/semaphore.h> |
| 17 | #include <asm/imalloc.h> | ||
| 17 | 18 | ||
| 18 | static DECLARE_MUTEX(imlist_sem); | 19 | static DECLARE_MUTEX(imlist_sem); |
| 19 | struct vm_struct * imlist = NULL; | 20 | struct vm_struct * imlist = NULL; |
| @@ -23,11 +24,11 @@ static int get_free_im_addr(unsigned long size, unsigned long *im_addr) | |||
| 23 | unsigned long addr; | 24 | unsigned long addr; |
| 24 | struct vm_struct **p, *tmp; | 25 | struct vm_struct **p, *tmp; |
| 25 | 26 | ||
| 26 | addr = IMALLOC_START; | 27 | addr = ioremap_bot; |
| 27 | for (p = &imlist; (tmp = *p) ; p = &tmp->next) { | 28 | for (p = &imlist; (tmp = *p) ; p = &tmp->next) { |
| 28 | if (size + addr < (unsigned long) tmp->addr) | 29 | if (size + addr < (unsigned long) tmp->addr) |
| 29 | break; | 30 | break; |
| 30 | if ((unsigned long)tmp->addr >= IMALLOC_START) | 31 | if ((unsigned long)tmp->addr >= ioremap_bot) |
| 31 | addr = tmp->size + (unsigned long) tmp->addr; | 32 | addr = tmp->size + (unsigned long) tmp->addr; |
| 32 | if (addr > IMALLOC_END-size) | 33 | if (addr > IMALLOC_END-size) |
| 33 | return 1; | 34 | return 1; |
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index a7149b9fc35c..4b42aff74d73 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c | |||
| @@ -64,6 +64,7 @@ | |||
| 64 | #include <asm/iommu.h> | 64 | #include <asm/iommu.h> |
| 65 | #include <asm/abs_addr.h> | 65 | #include <asm/abs_addr.h> |
| 66 | #include <asm/vdso.h> | 66 | #include <asm/vdso.h> |
| 67 | #include <asm/imalloc.h> | ||
| 67 | 68 | ||
| 68 | int mem_init_done; | 69 | int mem_init_done; |
| 69 | unsigned long ioremap_bot = IMALLOC_BASE; | 70 | unsigned long ioremap_bot = IMALLOC_BASE; |
| @@ -136,14 +137,78 @@ void iounmap(volatile void __iomem *addr) | |||
| 136 | 137 | ||
| 137 | #else | 138 | #else |
| 138 | 139 | ||
| 140 | static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr, | ||
| 141 | unsigned long end) | ||
| 142 | { | ||
| 143 | pte_t *pte; | ||
| 144 | |||
| 145 | pte = pte_offset_kernel(pmd, addr); | ||
| 146 | do { | ||
| 147 | pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte); | ||
| 148 | WARN_ON(!pte_none(ptent) && !pte_present(ptent)); | ||
| 149 | } while (pte++, addr += PAGE_SIZE, addr != end); | ||
| 150 | } | ||
| 151 | |||
| 152 | static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr, | ||
| 153 | unsigned long end) | ||
| 154 | { | ||
| 155 | pmd_t *pmd; | ||
| 156 | unsigned long next; | ||
| 157 | |||
| 158 | pmd = pmd_offset(pud, addr); | ||
| 159 | do { | ||
| 160 | next = pmd_addr_end(addr, end); | ||
| 161 | if (pmd_none_or_clear_bad(pmd)) | ||
| 162 | continue; | ||
| 163 | unmap_im_area_pte(pmd, addr, next); | ||
| 164 | } while (pmd++, addr = next, addr != end); | ||
| 165 | } | ||
| 166 | |||
| 167 | static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr, | ||
| 168 | unsigned long end) | ||
| 169 | { | ||
| 170 | pud_t *pud; | ||
| 171 | unsigned long next; | ||
| 172 | |||
| 173 | pud = pud_offset(pgd, addr); | ||
| 174 | do { | ||
| 175 | next = pud_addr_end(addr, end); | ||
| 176 | if (pud_none_or_clear_bad(pud)) | ||
| 177 | continue; | ||
| 178 | unmap_im_area_pmd(pud, addr, next); | ||
| 179 | } while (pud++, addr = next, addr != end); | ||
| 180 | } | ||
| 181 | |||
| 182 | static void unmap_im_area(unsigned long addr, unsigned long end) | ||
| 183 | { | ||
| 184 | struct mm_struct *mm = &ioremap_mm; | ||
| 185 | unsigned long next; | ||
| 186 | pgd_t *pgd; | ||
| 187 | |||
| 188 | spin_lock(&mm->page_table_lock); | ||
| 189 | |||
| 190 | pgd = pgd_offset_i(addr); | ||
| 191 | flush_cache_vunmap(addr, end); | ||
| 192 | do { | ||
| 193 | next = pgd_addr_end(addr, end); | ||
| 194 | if (pgd_none_or_clear_bad(pgd)) | ||
| 195 | continue; | ||
| 196 | unmap_im_area_pud(pgd, addr, next); | ||
| 197 | } while (pgd++, addr = next, addr != end); | ||
| 198 | flush_tlb_kernel_range(start, end); | ||
| 199 | |||
| 200 | spin_unlock(&mm->page_table_lock); | ||
| 201 | } | ||
| 202 | |||
| 139 | /* | 203 | /* |
| 140 | * map_io_page currently only called by __ioremap | 204 | * map_io_page currently only called by __ioremap |
| 141 | * map_io_page adds an entry to the ioremap page table | 205 | * map_io_page adds an entry to the ioremap page table |
| 142 | * and adds an entry to the HPT, possibly bolting it | 206 | * and adds an entry to the HPT, possibly bolting it |
| 143 | */ | 207 | */ |
| 144 | static void map_io_page(unsigned long ea, unsigned long pa, int flags) | 208 | static int map_io_page(unsigned long ea, unsigned long pa, int flags) |
| 145 | { | 209 | { |
| 146 | pgd_t *pgdp; | 210 | pgd_t *pgdp; |
| 211 | pud_t *pudp; | ||
| 147 | pmd_t *pmdp; | 212 | pmd_t *pmdp; |
| 148 | pte_t *ptep; | 213 | pte_t *ptep; |
| 149 | unsigned long vsid; | 214 | unsigned long vsid; |
| @@ -151,9 +216,15 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags) | |||
| 151 | if (mem_init_done) { | 216 | if (mem_init_done) { |
| 152 | spin_lock(&ioremap_mm.page_table_lock); | 217 | spin_lock(&ioremap_mm.page_table_lock); |
| 153 | pgdp = pgd_offset_i(ea); | 218 | pgdp = pgd_offset_i(ea); |
| 154 | pmdp = pmd_alloc(&ioremap_mm, pgdp, ea); | 219 | pudp = pud_alloc(&ioremap_mm, pgdp, ea); |
| 220 | if (!pudp) | ||
| 221 | return -ENOMEM; | ||
| 222 | pmdp = pmd_alloc(&ioremap_mm, pudp, ea); | ||
| 223 | if (!pmdp) | ||
| 224 | return -ENOMEM; | ||
| 155 | ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); | 225 | ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); |
| 156 | 226 | if (!ptep) | |
| 227 | return -ENOMEM; | ||
| 157 | pa = abs_to_phys(pa); | 228 | pa = abs_to_phys(pa); |
| 158 | set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, | 229 | set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, |
| 159 | __pgprot(flags))); | 230 | __pgprot(flags))); |
| @@ -181,6 +252,7 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags) | |||
| 181 | panic("map_io_page: could not insert mapping"); | 252 | panic("map_io_page: could not insert mapping"); |
| 182 | } | 253 | } |
| 183 | } | 254 | } |
| 255 | return 0; | ||
| 184 | } | 256 | } |
| 185 | 257 | ||
| 186 | 258 | ||
| @@ -194,9 +266,14 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, | |||
| 194 | flags |= pgprot_val(PAGE_KERNEL); | 266 | flags |= pgprot_val(PAGE_KERNEL); |
| 195 | 267 | ||
| 196 | for (i = 0; i < size; i += PAGE_SIZE) | 268 | for (i = 0; i < size; i += PAGE_SIZE) |
| 197 | map_io_page(ea+i, pa+i, flags); | 269 | if (map_io_page(ea+i, pa+i, flags)) |
| 270 | goto failure; | ||
| 198 | 271 | ||
| 199 | return (void __iomem *) (ea + (addr & ~PAGE_MASK)); | 272 | return (void __iomem *) (ea + (addr & ~PAGE_MASK)); |
| 273 | failure: | ||
| 274 | if (mem_init_done) | ||
| 275 | unmap_im_area(ea, ea + size); | ||
| 276 | return NULL; | ||
| 200 | } | 277 | } |
| 201 | 278 | ||
| 202 | 279 | ||
| @@ -206,10 +283,11 @@ ioremap(unsigned long addr, unsigned long size) | |||
| 206 | return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); | 283 | return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); |
| 207 | } | 284 | } |
| 208 | 285 | ||
| 209 | void __iomem * | 286 | void __iomem * __ioremap(unsigned long addr, unsigned long size, |
| 210 | __ioremap(unsigned long addr, unsigned long size, unsigned long flags) | 287 | unsigned long flags) |
| 211 | { | 288 | { |
| 212 | unsigned long pa, ea; | 289 | unsigned long pa, ea; |
| 290 | void __iomem *ret; | ||
| 213 | 291 | ||
| 214 | /* | 292 | /* |
| 215 | * Choose an address to map it to. | 293 | * Choose an address to map it to. |
| @@ -232,12 +310,16 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) | |||
| 232 | if (area == NULL) | 310 | if (area == NULL) |
| 233 | return NULL; | 311 | return NULL; |
| 234 | ea = (unsigned long)(area->addr); | 312 | ea = (unsigned long)(area->addr); |
| 313 | ret = __ioremap_com(addr, pa, ea, size, flags); | ||
| 314 | if (!ret) | ||
| 315 | im_free(area->addr); | ||
| 235 | } else { | 316 | } else { |
| 236 | ea = ioremap_bot; | 317 | ea = ioremap_bot; |
| 237 | ioremap_bot += size; | 318 | ret = __ioremap_com(addr, pa, ea, size, flags); |
| 319 | if (ret) | ||
| 320 | ioremap_bot += size; | ||
| 238 | } | 321 | } |
| 239 | 322 | return ret; | |
| 240 | return __ioremap_com(addr, pa, ea, size, flags); | ||
| 241 | } | 323 | } |
| 242 | 324 | ||
| 243 | #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) | 325 | #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) |
| @@ -246,6 +328,7 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, | |||
| 246 | unsigned long size, unsigned long flags) | 328 | unsigned long size, unsigned long flags) |
| 247 | { | 329 | { |
| 248 | struct vm_struct *area; | 330 | struct vm_struct *area; |
| 331 | void __iomem *ret; | ||
| 249 | 332 | ||
| 250 | /* For now, require page-aligned values for pa, ea, and size */ | 333 | /* For now, require page-aligned values for pa, ea, and size */ |
| 251 | if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) || | 334 | if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) || |
| @@ -276,7 +359,12 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, | |||
| 276 | } | 359 | } |
| 277 | } | 360 | } |
| 278 | 361 | ||
| 279 | if (__ioremap_com(pa, pa, ea, size, flags) != (void *) ea) { | 362 | ret = __ioremap_com(pa, pa, ea, size, flags); |
| 363 | if (ret == NULL) { | ||
| 364 | printk(KERN_ERR "ioremap_explicit() allocation failure !\n"); | ||
| 365 | return 1; | ||
| 366 | } | ||
| 367 | if (ret != (void *) ea) { | ||
| 280 | printk(KERN_ERR "__ioremap_com() returned unexpected addr\n"); | 368 | printk(KERN_ERR "__ioremap_com() returned unexpected addr\n"); |
| 281 | return 1; | 369 | return 1; |
| 282 | } | 370 | } |
| @@ -284,69 +372,6 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, | |||
| 284 | return 0; | 372 | return 0; |
| 285 | } | 373 | } |
| 286 | 374 | ||
| 287 | static void unmap_im_area_pte(pmd_t *pmd, unsigned long address, | ||
| 288 | unsigned long size) | ||
| 289 | { | ||
| 290 | unsigned long base, end; | ||
| 291 | pte_t *pte; | ||
| 292 | |||
| 293 | if (pmd_none(*pmd)) | ||
| 294 | return; | ||
| 295 | if (pmd_bad(*pmd)) { | ||
| 296 | pmd_ERROR(*pmd); | ||
| 297 | pmd_clear(pmd); | ||
| 298 | return; | ||
| 299 | } | ||
| 300 | |||
| 301 | pte = pte_offset_kernel(pmd, address); | ||
| 302 | base = address & PMD_MASK; | ||
| 303 | address &= ~PMD_MASK; | ||
| 304 | end = address + size; | ||
| 305 | if (end > PMD_SIZE) | ||
| 306 | end = PMD_SIZE; | ||
| 307 | |||
| 308 | do { | ||
| 309 | pte_t page; | ||
| 310 | page = ptep_get_and_clear(&ioremap_mm, base + address, pte); | ||
| 311 | address += PAGE_SIZE; | ||
| 312 | pte++; | ||
| 313 | if (pte_none(page)) | ||
| 314 | continue; | ||
| 315 | if (pte_present(page)) | ||
| 316 | continue; | ||
| 317 | printk(KERN_CRIT "Whee.. Swapped out page in kernel page" | ||
| 318 | " table\n"); | ||
| 319 | } while (address < end); | ||
| 320 | } | ||
| 321 | |||
| 322 | static void unmap_im_area_pmd(pgd_t *dir, unsigned long address, | ||
| 323 | unsigned long size) | ||
| 324 | { | ||
| 325 | unsigned long base, end; | ||
| 326 | pmd_t *pmd; | ||
| 327 | |||
| 328 | if (pgd_none(*dir)) | ||
| 329 | return; | ||
| 330 | if (pgd_bad(*dir)) { | ||
| 331 | pgd_ERROR(*dir); | ||
| 332 | pgd_clear(dir); | ||
| 333 | return; | ||
| 334 | } | ||
| 335 | |||
| 336 | pmd = pmd_offset(dir, address); | ||
| 337 | base = address & PGDIR_MASK; | ||
| 338 | address &= ~PGDIR_MASK; | ||
| 339 | end = address + size; | ||
| 340 | if (end > PGDIR_SIZE) | ||
| 341 | end = PGDIR_SIZE; | ||
| 342 | |||
| 343 | do { | ||
| 344 | unmap_im_area_pte(pmd, base + address, end - address); | ||
| 345 | address = (address + PMD_SIZE) & PMD_MASK; | ||
| 346 | pmd++; | ||
| 347 | } while (address < end); | ||
| 348 | } | ||
| 349 | |||
| 350 | /* | 375 | /* |
| 351 | * Unmap an IO region and remove it from imalloc'd list. | 376 | * Unmap an IO region and remove it from imalloc'd list. |
| 352 | * Access to IO memory should be serialized by driver. | 377 | * Access to IO memory should be serialized by driver. |
| @@ -356,39 +381,19 @@ static void unmap_im_area_pmd(pgd_t *dir, unsigned long address, | |||
| 356 | */ | 381 | */ |
| 357 | void iounmap(volatile void __iomem *token) | 382 | void iounmap(volatile void __iomem *token) |
| 358 | { | 383 | { |
| 359 | unsigned long address, start, end, size; | 384 | unsigned long address, size; |
| 360 | struct mm_struct *mm; | ||
| 361 | pgd_t *dir; | ||
| 362 | void *addr; | 385 | void *addr; |
| 363 | 386 | ||
| 364 | if (!mem_init_done) { | 387 | if (!mem_init_done) |
| 365 | return; | 388 | return; |
| 366 | } | ||
| 367 | 389 | ||
| 368 | addr = (void *) ((unsigned long __force) token & PAGE_MASK); | 390 | addr = (void *) ((unsigned long __force) token & PAGE_MASK); |
| 369 | 391 | ||
| 370 | if ((size = im_free(addr)) == 0) { | 392 | if ((size = im_free(addr)) == 0) |
| 371 | return; | 393 | return; |
| 372 | } | ||
| 373 | 394 | ||
| 374 | address = (unsigned long)addr; | 395 | address = (unsigned long)addr; |
| 375 | start = address; | 396 | unmap_im_area(address, address + size); |
| 376 | end = address + size; | ||
| 377 | |||
| 378 | mm = &ioremap_mm; | ||
| 379 | spin_lock(&mm->page_table_lock); | ||
| 380 | |||
| 381 | dir = pgd_offset_i(address); | ||
| 382 | flush_cache_vunmap(address, end); | ||
| 383 | do { | ||
| 384 | unmap_im_area_pmd(dir, address, end - address); | ||
| 385 | address = (address + PGDIR_SIZE) & PGDIR_MASK; | ||
| 386 | dir++; | ||
| 387 | } while (address && (address < end)); | ||
| 388 | flush_tlb_kernel_range(start, end); | ||
| 389 | |||
| 390 | spin_unlock(&mm->page_table_lock); | ||
| 391 | return; | ||
| 392 | } | 397 | } |
| 393 | 398 | ||
| 394 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) | 399 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) |
| @@ -664,7 +669,7 @@ void __init paging_init(void) | |||
| 664 | zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; | 669 | zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; |
| 665 | zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; | 670 | zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; |
| 666 | 671 | ||
| 667 | free_area_init_node(0, &contig_page_data, zones_size, | 672 | free_area_init_node(0, NODE_DATA(0), zones_size, |
| 668 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); | 673 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); |
| 669 | } | 674 | } |
| 670 | #endif /* CONFIG_DISCONTIGMEM */ | 675 | #endif /* CONFIG_DISCONTIGMEM */ |
diff --git a/arch/ppc64/mm/slb.c b/arch/ppc64/mm/slb.c index 6a20773f695d..244150a0bc18 100644 --- a/arch/ppc64/mm/slb.c +++ b/arch/ppc64/mm/slb.c | |||
| @@ -33,8 +33,8 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags) | |||
| 33 | return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; | 33 | return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static inline void create_slbe(unsigned long ea, unsigned long vsid, | 36 | static inline void create_slbe(unsigned long ea, unsigned long flags, |
| 37 | unsigned long flags, unsigned long entry) | 37 | unsigned long entry) |
| 38 | { | 38 | { |
| 39 | asm volatile("slbmte %0,%1" : | 39 | asm volatile("slbmte %0,%1" : |
| 40 | : "r" (mk_vsid_data(ea, flags)), | 40 | : "r" (mk_vsid_data(ea, flags)), |
| @@ -145,9 +145,8 @@ void slb_initialize(void) | |||
| 145 | asm volatile("isync":::"memory"); | 145 | asm volatile("isync":::"memory"); |
| 146 | asm volatile("slbmte %0,%0"::"r" (0) : "memory"); | 146 | asm volatile("slbmte %0,%0"::"r" (0) : "memory"); |
| 147 | asm volatile("isync; slbia; isync":::"memory"); | 147 | asm volatile("isync; slbia; isync":::"memory"); |
| 148 | create_slbe(KERNELBASE, get_kernel_vsid(KERNELBASE), flags, 0); | 148 | create_slbe(KERNELBASE, flags, 0); |
| 149 | create_slbe(VMALLOCBASE, get_kernel_vsid(KERNELBASE), | 149 | create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1); |
| 150 | SLB_VSID_KERNEL, 1); | ||
| 151 | /* We don't bolt the stack for the time being - we're in boot, | 150 | /* We don't bolt the stack for the time being - we're in boot, |
| 152 | * so the stack is in the bolted segment. By the time it goes | 151 | * so the stack is in the bolted segment. By the time it goes |
| 153 | * elsewhere, we'll call _switch() which will bolt in the new | 152 | * elsewhere, we'll call _switch() which will bolt in the new |
diff --git a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c index 31491131d5e4..df4bbe14153c 100644 --- a/arch/ppc64/mm/stab.c +++ b/arch/ppc64/mm/stab.c | |||
| @@ -19,6 +19,11 @@ | |||
| 19 | #include <asm/paca.h> | 19 | #include <asm/paca.h> |
| 20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
| 21 | 21 | ||
| 22 | struct stab_entry { | ||
| 23 | unsigned long esid_data; | ||
| 24 | unsigned long vsid_data; | ||
| 25 | }; | ||
| 26 | |||
| 22 | /* Both the segment table and SLB code uses the following cache */ | 27 | /* Both the segment table and SLB code uses the following cache */ |
| 23 | #define NR_STAB_CACHE_ENTRIES 8 | 28 | #define NR_STAB_CACHE_ENTRIES 8 |
| 24 | DEFINE_PER_CPU(long, stab_cache_ptr); | 29 | DEFINE_PER_CPU(long, stab_cache_ptr); |
diff --git a/arch/ppc64/xmon/ppc-opc.c b/arch/ppc64/xmon/ppc-opc.c index 1e4e7e319970..5ee8fc32f824 100644 --- a/arch/ppc64/xmon/ppc-opc.c +++ b/arch/ppc64/xmon/ppc-opc.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | 20 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA |
| 21 | 02111-1307, USA. */ | 21 | 02111-1307, USA. */ |
| 22 | 22 | ||
| 23 | #include <linux/stddef.h> | ||
| 23 | #include "nonstdio.h" | 24 | #include "nonstdio.h" |
| 24 | #include "ppc.h" | 25 | #include "ppc.h" |
| 25 | 26 | ||
| @@ -110,12 +111,12 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 110 | /* The zero index is used to indicate the end of the list of | 111 | /* The zero index is used to indicate the end of the list of |
| 111 | operands. */ | 112 | operands. */ |
| 112 | #define UNUSED 0 | 113 | #define UNUSED 0 |
| 113 | { 0, 0, 0, 0, 0 }, | 114 | { 0, 0, NULL, NULL, 0 }, |
| 114 | 115 | ||
| 115 | /* The BA field in an XL form instruction. */ | 116 | /* The BA field in an XL form instruction. */ |
| 116 | #define BA UNUSED + 1 | 117 | #define BA UNUSED + 1 |
| 117 | #define BA_MASK (0x1f << 16) | 118 | #define BA_MASK (0x1f << 16) |
| 118 | { 5, 16, 0, 0, PPC_OPERAND_CR }, | 119 | { 5, 16, NULL, NULL, PPC_OPERAND_CR }, |
| 119 | 120 | ||
| 120 | /* The BA field in an XL form instruction when it must be the same | 121 | /* The BA field in an XL form instruction when it must be the same |
| 121 | as the BT field in the same instruction. */ | 122 | as the BT field in the same instruction. */ |
| @@ -125,7 +126,7 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 125 | /* The BB field in an XL form instruction. */ | 126 | /* The BB field in an XL form instruction. */ |
| 126 | #define BB BAT + 1 | 127 | #define BB BAT + 1 |
| 127 | #define BB_MASK (0x1f << 11) | 128 | #define BB_MASK (0x1f << 11) |
| 128 | { 5, 11, 0, 0, PPC_OPERAND_CR }, | 129 | { 5, 11, NULL, NULL, PPC_OPERAND_CR }, |
| 129 | 130 | ||
| 130 | /* The BB field in an XL form instruction when it must be the same | 131 | /* The BB field in an XL form instruction when it must be the same |
| 131 | as the BA field in the same instruction. */ | 132 | as the BA field in the same instruction. */ |
| @@ -168,21 +169,21 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 168 | 169 | ||
| 169 | /* The BF field in an X or XL form instruction. */ | 170 | /* The BF field in an X or XL form instruction. */ |
| 170 | #define BF BDPA + 1 | 171 | #define BF BDPA + 1 |
| 171 | { 3, 23, 0, 0, PPC_OPERAND_CR }, | 172 | { 3, 23, NULL, NULL, PPC_OPERAND_CR }, |
| 172 | 173 | ||
| 173 | /* An optional BF field. This is used for comparison instructions, | 174 | /* An optional BF field. This is used for comparison instructions, |
| 174 | in which an omitted BF field is taken as zero. */ | 175 | in which an omitted BF field is taken as zero. */ |
| 175 | #define OBF BF + 1 | 176 | #define OBF BF + 1 |
| 176 | { 3, 23, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, | 177 | { 3, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, |
| 177 | 178 | ||
| 178 | /* The BFA field in an X or XL form instruction. */ | 179 | /* The BFA field in an X or XL form instruction. */ |
| 179 | #define BFA OBF + 1 | 180 | #define BFA OBF + 1 |
| 180 | { 3, 18, 0, 0, PPC_OPERAND_CR }, | 181 | { 3, 18, NULL, NULL, PPC_OPERAND_CR }, |
| 181 | 182 | ||
| 182 | /* The BI field in a B form or XL form instruction. */ | 183 | /* The BI field in a B form or XL form instruction. */ |
| 183 | #define BI BFA + 1 | 184 | #define BI BFA + 1 |
| 184 | #define BI_MASK (0x1f << 16) | 185 | #define BI_MASK (0x1f << 16) |
| 185 | { 5, 16, 0, 0, PPC_OPERAND_CR }, | 186 | { 5, 16, NULL, NULL, PPC_OPERAND_CR }, |
| 186 | 187 | ||
| 187 | /* The BO field in a B form instruction. Certain values are | 188 | /* The BO field in a B form instruction. Certain values are |
| 188 | illegal. */ | 189 | illegal. */ |
| @@ -197,36 +198,36 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 197 | 198 | ||
| 198 | /* The BT field in an X or XL form instruction. */ | 199 | /* The BT field in an X or XL form instruction. */ |
| 199 | #define BT BOE + 1 | 200 | #define BT BOE + 1 |
| 200 | { 5, 21, 0, 0, PPC_OPERAND_CR }, | 201 | { 5, 21, NULL, NULL, PPC_OPERAND_CR }, |
| 201 | 202 | ||
| 202 | /* The condition register number portion of the BI field in a B form | 203 | /* The condition register number portion of the BI field in a B form |
| 203 | or XL form instruction. This is used for the extended | 204 | or XL form instruction. This is used for the extended |
| 204 | conditional branch mnemonics, which set the lower two bits of the | 205 | conditional branch mnemonics, which set the lower two bits of the |
| 205 | BI field. This field is optional. */ | 206 | BI field. This field is optional. */ |
| 206 | #define CR BT + 1 | 207 | #define CR BT + 1 |
| 207 | { 3, 18, 0, 0, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, | 208 | { 3, 18, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL }, |
| 208 | 209 | ||
| 209 | /* The CRB field in an X form instruction. */ | 210 | /* The CRB field in an X form instruction. */ |
| 210 | #define CRB CR + 1 | 211 | #define CRB CR + 1 |
| 211 | { 5, 6, 0, 0, 0 }, | 212 | { 5, 6, NULL, NULL, 0 }, |
| 212 | 213 | ||
| 213 | /* The CRFD field in an X form instruction. */ | 214 | /* The CRFD field in an X form instruction. */ |
| 214 | #define CRFD CRB + 1 | 215 | #define CRFD CRB + 1 |
| 215 | { 3, 23, 0, 0, PPC_OPERAND_CR }, | 216 | { 3, 23, NULL, NULL, PPC_OPERAND_CR }, |
| 216 | 217 | ||
| 217 | /* The CRFS field in an X form instruction. */ | 218 | /* The CRFS field in an X form instruction. */ |
| 218 | #define CRFS CRFD + 1 | 219 | #define CRFS CRFD + 1 |
| 219 | { 3, 0, 0, 0, PPC_OPERAND_CR }, | 220 | { 3, 0, NULL, NULL, PPC_OPERAND_CR }, |
| 220 | 221 | ||
| 221 | /* The CT field in an X form instruction. */ | 222 | /* The CT field in an X form instruction. */ |
| 222 | #define CT CRFS + 1 | 223 | #define CT CRFS + 1 |
| 223 | { 5, 21, 0, 0, PPC_OPERAND_OPTIONAL }, | 224 | { 5, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, |
| 224 | 225 | ||
| 225 | /* The D field in a D form instruction. This is a displacement off | 226 | /* The D field in a D form instruction. This is a displacement off |
| 226 | a register, and implies that the next operand is a register in | 227 | a register, and implies that the next operand is a register in |
| 227 | parentheses. */ | 228 | parentheses. */ |
| 228 | #define D CT + 1 | 229 | #define D CT + 1 |
| 229 | { 16, 0, 0, 0, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, | 230 | { 16, 0, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, |
| 230 | 231 | ||
| 231 | /* The DE field in a DE form instruction. This is like D, but is 12 | 232 | /* The DE field in a DE form instruction. This is like D, but is 12 |
| 232 | bits only. */ | 233 | bits only. */ |
| @@ -252,40 +253,40 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 252 | 253 | ||
| 253 | /* The E field in a wrteei instruction. */ | 254 | /* The E field in a wrteei instruction. */ |
| 254 | #define E DS + 1 | 255 | #define E DS + 1 |
| 255 | { 1, 15, 0, 0, 0 }, | 256 | { 1, 15, NULL, NULL, 0 }, |
| 256 | 257 | ||
| 257 | /* The FL1 field in a POWER SC form instruction. */ | 258 | /* The FL1 field in a POWER SC form instruction. */ |
| 258 | #define FL1 E + 1 | 259 | #define FL1 E + 1 |
| 259 | { 4, 12, 0, 0, 0 }, | 260 | { 4, 12, NULL, NULL, 0 }, |
| 260 | 261 | ||
| 261 | /* The FL2 field in a POWER SC form instruction. */ | 262 | /* The FL2 field in a POWER SC form instruction. */ |
| 262 | #define FL2 FL1 + 1 | 263 | #define FL2 FL1 + 1 |
| 263 | { 3, 2, 0, 0, 0 }, | 264 | { 3, 2, NULL, NULL, 0 }, |
| 264 | 265 | ||
| 265 | /* The FLM field in an XFL form instruction. */ | 266 | /* The FLM field in an XFL form instruction. */ |
| 266 | #define FLM FL2 + 1 | 267 | #define FLM FL2 + 1 |
| 267 | { 8, 17, 0, 0, 0 }, | 268 | { 8, 17, NULL, NULL, 0 }, |
| 268 | 269 | ||
| 269 | /* The FRA field in an X or A form instruction. */ | 270 | /* The FRA field in an X or A form instruction. */ |
| 270 | #define FRA FLM + 1 | 271 | #define FRA FLM + 1 |
| 271 | #define FRA_MASK (0x1f << 16) | 272 | #define FRA_MASK (0x1f << 16) |
| 272 | { 5, 16, 0, 0, PPC_OPERAND_FPR }, | 273 | { 5, 16, NULL, NULL, PPC_OPERAND_FPR }, |
| 273 | 274 | ||
| 274 | /* The FRB field in an X or A form instruction. */ | 275 | /* The FRB field in an X or A form instruction. */ |
| 275 | #define FRB FRA + 1 | 276 | #define FRB FRA + 1 |
| 276 | #define FRB_MASK (0x1f << 11) | 277 | #define FRB_MASK (0x1f << 11) |
| 277 | { 5, 11, 0, 0, PPC_OPERAND_FPR }, | 278 | { 5, 11, NULL, NULL, PPC_OPERAND_FPR }, |
| 278 | 279 | ||
| 279 | /* The FRC field in an A form instruction. */ | 280 | /* The FRC field in an A form instruction. */ |
| 280 | #define FRC FRB + 1 | 281 | #define FRC FRB + 1 |
| 281 | #define FRC_MASK (0x1f << 6) | 282 | #define FRC_MASK (0x1f << 6) |
| 282 | { 5, 6, 0, 0, PPC_OPERAND_FPR }, | 283 | { 5, 6, NULL, NULL, PPC_OPERAND_FPR }, |
| 283 | 284 | ||
| 284 | /* The FRS field in an X form instruction or the FRT field in a D, X | 285 | /* The FRS field in an X form instruction or the FRT field in a D, X |
| 285 | or A form instruction. */ | 286 | or A form instruction. */ |
| 286 | #define FRS FRC + 1 | 287 | #define FRS FRC + 1 |
| 287 | #define FRT FRS | 288 | #define FRT FRS |
| 288 | { 5, 21, 0, 0, PPC_OPERAND_FPR }, | 289 | { 5, 21, NULL, NULL, PPC_OPERAND_FPR }, |
| 289 | 290 | ||
| 290 | /* The FXM field in an XFX instruction. */ | 291 | /* The FXM field in an XFX instruction. */ |
| 291 | #define FXM FRS + 1 | 292 | #define FXM FRS + 1 |
| @@ -298,11 +299,11 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 298 | 299 | ||
| 299 | /* The L field in a D or X form instruction. */ | 300 | /* The L field in a D or X form instruction. */ |
| 300 | #define L FXM4 + 1 | 301 | #define L FXM4 + 1 |
| 301 | { 1, 21, 0, 0, PPC_OPERAND_OPTIONAL }, | 302 | { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, |
| 302 | 303 | ||
| 303 | /* The LEV field in a POWER SC form instruction. */ | 304 | /* The LEV field in a POWER SC form instruction. */ |
| 304 | #define LEV L + 1 | 305 | #define LEV L + 1 |
| 305 | { 7, 5, 0, 0, 0 }, | 306 | { 7, 5, NULL, NULL, 0 }, |
| 306 | 307 | ||
| 307 | /* The LI field in an I form instruction. The lower two bits are | 308 | /* The LI field in an I form instruction. The lower two bits are |
| 308 | forced to zero. */ | 309 | forced to zero. */ |
| @@ -316,24 +317,24 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 316 | 317 | ||
| 317 | /* The LS field in an X (sync) form instruction. */ | 318 | /* The LS field in an X (sync) form instruction. */ |
| 318 | #define LS LIA + 1 | 319 | #define LS LIA + 1 |
| 319 | { 2, 21, 0, 0, PPC_OPERAND_OPTIONAL }, | 320 | { 2, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, |
| 320 | 321 | ||
| 321 | /* The MB field in an M form instruction. */ | 322 | /* The MB field in an M form instruction. */ |
| 322 | #define MB LS + 1 | 323 | #define MB LS + 1 |
| 323 | #define MB_MASK (0x1f << 6) | 324 | #define MB_MASK (0x1f << 6) |
| 324 | { 5, 6, 0, 0, 0 }, | 325 | { 5, 6, NULL, NULL, 0 }, |
| 325 | 326 | ||
| 326 | /* The ME field in an M form instruction. */ | 327 | /* The ME field in an M form instruction. */ |
| 327 | #define ME MB + 1 | 328 | #define ME MB + 1 |
| 328 | #define ME_MASK (0x1f << 1) | 329 | #define ME_MASK (0x1f << 1) |
| 329 | { 5, 1, 0, 0, 0 }, | 330 | { 5, 1, NULL, NULL, 0 }, |
| 330 | 331 | ||
| 331 | /* The MB and ME fields in an M form instruction expressed a single | 332 | /* The MB and ME fields in an M form instruction expressed a single |
| 332 | operand which is a bitmask indicating which bits to select. This | 333 | operand which is a bitmask indicating which bits to select. This |
| 333 | is a two operand form using PPC_OPERAND_NEXT. See the | 334 | is a two operand form using PPC_OPERAND_NEXT. See the |
| 334 | description in opcode/ppc.h for what this means. */ | 335 | description in opcode/ppc.h for what this means. */ |
| 335 | #define MBE ME + 1 | 336 | #define MBE ME + 1 |
| 336 | { 5, 6, 0, 0, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT }, | 337 | { 5, 6, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT }, |
| 337 | { 32, 0, insert_mbe, extract_mbe, 0 }, | 338 | { 32, 0, insert_mbe, extract_mbe, 0 }, |
| 338 | 339 | ||
| 339 | /* The MB or ME field in an MD or MDS form instruction. The high | 340 | /* The MB or ME field in an MD or MDS form instruction. The high |
| @@ -345,7 +346,7 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 345 | 346 | ||
| 346 | /* The MO field in an mbar instruction. */ | 347 | /* The MO field in an mbar instruction. */ |
| 347 | #define MO MB6 + 1 | 348 | #define MO MB6 + 1 |
| 348 | { 5, 21, 0, 0, 0 }, | 349 | { 5, 21, NULL, NULL, 0 }, |
| 349 | 350 | ||
| 350 | /* The NB field in an X form instruction. The value 32 is stored as | 351 | /* The NB field in an X form instruction. The value 32 is stored as |
| 351 | 0. */ | 352 | 0. */ |
| @@ -361,34 +362,34 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 361 | /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */ | 362 | /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */ |
| 362 | #define RA NSI + 1 | 363 | #define RA NSI + 1 |
| 363 | #define RA_MASK (0x1f << 16) | 364 | #define RA_MASK (0x1f << 16) |
| 364 | { 5, 16, 0, 0, PPC_OPERAND_GPR }, | 365 | { 5, 16, NULL, NULL, PPC_OPERAND_GPR }, |
| 365 | 366 | ||
| 366 | /* The RA field in the DQ form lq instruction, which has special | 367 | /* The RA field in the DQ form lq instruction, which has special |
| 367 | value restrictions. */ | 368 | value restrictions. */ |
| 368 | #define RAQ RA + 1 | 369 | #define RAQ RA + 1 |
| 369 | { 5, 16, insert_raq, 0, PPC_OPERAND_GPR }, | 370 | { 5, 16, insert_raq, NULL, PPC_OPERAND_GPR }, |
| 370 | 371 | ||
| 371 | /* The RA field in a D or X form instruction which is an updating | 372 | /* The RA field in a D or X form instruction which is an updating |
| 372 | load, which means that the RA field may not be zero and may not | 373 | load, which means that the RA field may not be zero and may not |
| 373 | equal the RT field. */ | 374 | equal the RT field. */ |
| 374 | #define RAL RAQ + 1 | 375 | #define RAL RAQ + 1 |
| 375 | { 5, 16, insert_ral, 0, PPC_OPERAND_GPR }, | 376 | { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR }, |
| 376 | 377 | ||
| 377 | /* The RA field in an lmw instruction, which has special value | 378 | /* The RA field in an lmw instruction, which has special value |
| 378 | restrictions. */ | 379 | restrictions. */ |
| 379 | #define RAM RAL + 1 | 380 | #define RAM RAL + 1 |
| 380 | { 5, 16, insert_ram, 0, PPC_OPERAND_GPR }, | 381 | { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR }, |
| 381 | 382 | ||
| 382 | /* The RA field in a D or X form instruction which is an updating | 383 | /* The RA field in a D or X form instruction which is an updating |
| 383 | store or an updating floating point load, which means that the RA | 384 | store or an updating floating point load, which means that the RA |
| 384 | field may not be zero. */ | 385 | field may not be zero. */ |
| 385 | #define RAS RAM + 1 | 386 | #define RAS RAM + 1 |
| 386 | { 5, 16, insert_ras, 0, PPC_OPERAND_GPR }, | 387 | { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR }, |
| 387 | 388 | ||
| 388 | /* The RB field in an X, XO, M, or MDS form instruction. */ | 389 | /* The RB field in an X, XO, M, or MDS form instruction. */ |
| 389 | #define RB RAS + 1 | 390 | #define RB RAS + 1 |
| 390 | #define RB_MASK (0x1f << 11) | 391 | #define RB_MASK (0x1f << 11) |
| 391 | { 5, 11, 0, 0, PPC_OPERAND_GPR }, | 392 | { 5, 11, NULL, NULL, PPC_OPERAND_GPR }, |
| 392 | 393 | ||
| 393 | /* The RB field in an X form instruction when it must be the same as | 394 | /* The RB field in an X form instruction when it must be the same as |
| 394 | the RS field in the instruction. This is used for extended | 395 | the RS field in the instruction. This is used for extended |
| @@ -402,22 +403,22 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 402 | #define RS RBS + 1 | 403 | #define RS RBS + 1 |
| 403 | #define RT RS | 404 | #define RT RS |
| 404 | #define RT_MASK (0x1f << 21) | 405 | #define RT_MASK (0x1f << 21) |
| 405 | { 5, 21, 0, 0, PPC_OPERAND_GPR }, | 406 | { 5, 21, NULL, NULL, PPC_OPERAND_GPR }, |
| 406 | 407 | ||
| 407 | /* The RS field of the DS form stq instruction, which has special | 408 | /* The RS field of the DS form stq instruction, which has special |
| 408 | value restrictions. */ | 409 | value restrictions. */ |
| 409 | #define RSQ RS + 1 | 410 | #define RSQ RS + 1 |
| 410 | { 5, 21, insert_rsq, 0, PPC_OPERAND_GPR }, | 411 | { 5, 21, insert_rsq, NULL, PPC_OPERAND_GPR }, |
| 411 | 412 | ||
| 412 | /* The RT field of the DQ form lq instruction, which has special | 413 | /* The RT field of the DQ form lq instruction, which has special |
| 413 | value restrictions. */ | 414 | value restrictions. */ |
| 414 | #define RTQ RSQ + 1 | 415 | #define RTQ RSQ + 1 |
| 415 | { 5, 21, insert_rtq, 0, PPC_OPERAND_GPR }, | 416 | { 5, 21, insert_rtq, NULL, PPC_OPERAND_GPR }, |
| 416 | 417 | ||
| 417 | /* The SH field in an X or M form instruction. */ | 418 | /* The SH field in an X or M form instruction. */ |
| 418 | #define SH RTQ + 1 | 419 | #define SH RTQ + 1 |
| 419 | #define SH_MASK (0x1f << 11) | 420 | #define SH_MASK (0x1f << 11) |
| 420 | { 5, 11, 0, 0, 0 }, | 421 | { 5, 11, NULL, NULL, 0 }, |
| 421 | 422 | ||
| 422 | /* The SH field in an MD form instruction. This is split. */ | 423 | /* The SH field in an MD form instruction. This is split. */ |
| 423 | #define SH6 SH + 1 | 424 | #define SH6 SH + 1 |
| @@ -426,12 +427,12 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 426 | 427 | ||
| 427 | /* The SI field in a D form instruction. */ | 428 | /* The SI field in a D form instruction. */ |
| 428 | #define SI SH6 + 1 | 429 | #define SI SH6 + 1 |
| 429 | { 16, 0, 0, 0, PPC_OPERAND_SIGNED }, | 430 | { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED }, |
| 430 | 431 | ||
| 431 | /* The SI field in a D form instruction when we accept a wide range | 432 | /* The SI field in a D form instruction when we accept a wide range |
| 432 | of positive values. */ | 433 | of positive values. */ |
| 433 | #define SISIGNOPT SI + 1 | 434 | #define SISIGNOPT SI + 1 |
| 434 | { 16, 0, 0, 0, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT }, | 435 | { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT }, |
| 435 | 436 | ||
| 436 | /* The SPR field in an XFX form instruction. This is flipped--the | 437 | /* The SPR field in an XFX form instruction. This is flipped--the |
| 437 | lower 5 bits are stored in the upper 5 and vice- versa. */ | 438 | lower 5 bits are stored in the upper 5 and vice- versa. */ |
| @@ -443,25 +444,25 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 443 | /* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */ | 444 | /* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */ |
| 444 | #define SPRBAT SPR + 1 | 445 | #define SPRBAT SPR + 1 |
| 445 | #define SPRBAT_MASK (0x3 << 17) | 446 | #define SPRBAT_MASK (0x3 << 17) |
| 446 | { 2, 17, 0, 0, 0 }, | 447 | { 2, 17, NULL, NULL, 0 }, |
| 447 | 448 | ||
| 448 | /* The SPRG register number in an XFX form m[ft]sprg instruction. */ | 449 | /* The SPRG register number in an XFX form m[ft]sprg instruction. */ |
| 449 | #define SPRG SPRBAT + 1 | 450 | #define SPRG SPRBAT + 1 |
| 450 | #define SPRG_MASK (0x3 << 16) | 451 | #define SPRG_MASK (0x3 << 16) |
| 451 | { 2, 16, 0, 0, 0 }, | 452 | { 2, 16, NULL, NULL, 0 }, |
| 452 | 453 | ||
| 453 | /* The SR field in an X form instruction. */ | 454 | /* The SR field in an X form instruction. */ |
| 454 | #define SR SPRG + 1 | 455 | #define SR SPRG + 1 |
| 455 | { 4, 16, 0, 0, 0 }, | 456 | { 4, 16, NULL, NULL, 0 }, |
| 456 | 457 | ||
| 457 | /* The STRM field in an X AltiVec form instruction. */ | 458 | /* The STRM field in an X AltiVec form instruction. */ |
| 458 | #define STRM SR + 1 | 459 | #define STRM SR + 1 |
| 459 | #define STRM_MASK (0x3 << 21) | 460 | #define STRM_MASK (0x3 << 21) |
| 460 | { 2, 21, 0, 0, 0 }, | 461 | { 2, 21, NULL, NULL, 0 }, |
| 461 | 462 | ||
| 462 | /* The SV field in a POWER SC form instruction. */ | 463 | /* The SV field in a POWER SC form instruction. */ |
| 463 | #define SV STRM + 1 | 464 | #define SV STRM + 1 |
| 464 | { 14, 2, 0, 0, 0 }, | 465 | { 14, 2, NULL, NULL, 0 }, |
| 465 | 466 | ||
| 466 | /* The TBR field in an XFX form instruction. This is like the SPR | 467 | /* The TBR field in an XFX form instruction. This is like the SPR |
| 467 | field, but it is optional. */ | 468 | field, but it is optional. */ |
| @@ -471,52 +472,52 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 471 | /* The TO field in a D or X form instruction. */ | 472 | /* The TO field in a D or X form instruction. */ |
| 472 | #define TO TBR + 1 | 473 | #define TO TBR + 1 |
| 473 | #define TO_MASK (0x1f << 21) | 474 | #define TO_MASK (0x1f << 21) |
| 474 | { 5, 21, 0, 0, 0 }, | 475 | { 5, 21, NULL, NULL, 0 }, |
| 475 | 476 | ||
| 476 | /* The U field in an X form instruction. */ | 477 | /* The U field in an X form instruction. */ |
| 477 | #define U TO + 1 | 478 | #define U TO + 1 |
| 478 | { 4, 12, 0, 0, 0 }, | 479 | { 4, 12, NULL, NULL, 0 }, |
| 479 | 480 | ||
| 480 | /* The UI field in a D form instruction. */ | 481 | /* The UI field in a D form instruction. */ |
| 481 | #define UI U + 1 | 482 | #define UI U + 1 |
| 482 | { 16, 0, 0, 0, 0 }, | 483 | { 16, 0, NULL, NULL, 0 }, |
| 483 | 484 | ||
| 484 | /* The VA field in a VA, VX or VXR form instruction. */ | 485 | /* The VA field in a VA, VX or VXR form instruction. */ |
| 485 | #define VA UI + 1 | 486 | #define VA UI + 1 |
| 486 | #define VA_MASK (0x1f << 16) | 487 | #define VA_MASK (0x1f << 16) |
| 487 | { 5, 16, 0, 0, PPC_OPERAND_VR }, | 488 | { 5, 16, NULL, NULL, PPC_OPERAND_VR }, |
| 488 | 489 | ||
| 489 | /* The VB field in a VA, VX or VXR form instruction. */ | 490 | /* The VB field in a VA, VX or VXR form instruction. */ |
| 490 | #define VB VA + 1 | 491 | #define VB VA + 1 |
| 491 | #define VB_MASK (0x1f << 11) | 492 | #define VB_MASK (0x1f << 11) |
| 492 | { 5, 11, 0, 0, PPC_OPERAND_VR }, | 493 | { 5, 11, NULL, NULL, PPC_OPERAND_VR }, |
| 493 | 494 | ||
| 494 | /* The VC field in a VA form instruction. */ | 495 | /* The VC field in a VA form instruction. */ |
| 495 | #define VC VB + 1 | 496 | #define VC VB + 1 |
| 496 | #define VC_MASK (0x1f << 6) | 497 | #define VC_MASK (0x1f << 6) |
| 497 | { 5, 6, 0, 0, PPC_OPERAND_VR }, | 498 | { 5, 6, NULL, NULL, PPC_OPERAND_VR }, |
| 498 | 499 | ||
| 499 | /* The VD or VS field in a VA, VX, VXR or X form instruction. */ | 500 | /* The VD or VS field in a VA, VX, VXR or X form instruction. */ |
| 500 | #define VD VC + 1 | 501 | #define VD VC + 1 |
| 501 | #define VS VD | 502 | #define VS VD |
| 502 | #define VD_MASK (0x1f << 21) | 503 | #define VD_MASK (0x1f << 21) |
| 503 | { 5, 21, 0, 0, PPC_OPERAND_VR }, | 504 | { 5, 21, NULL, NULL, PPC_OPERAND_VR }, |
| 504 | 505 | ||
| 505 | /* The SIMM field in a VX form instruction. */ | 506 | /* The SIMM field in a VX form instruction. */ |
| 506 | #define SIMM VD + 1 | 507 | #define SIMM VD + 1 |
| 507 | { 5, 16, 0, 0, PPC_OPERAND_SIGNED}, | 508 | { 5, 16, NULL, NULL, PPC_OPERAND_SIGNED}, |
| 508 | 509 | ||
| 509 | /* The UIMM field in a VX form instruction. */ | 510 | /* The UIMM field in a VX form instruction. */ |
| 510 | #define UIMM SIMM + 1 | 511 | #define UIMM SIMM + 1 |
| 511 | { 5, 16, 0, 0, 0 }, | 512 | { 5, 16, NULL, NULL, 0 }, |
| 512 | 513 | ||
| 513 | /* The SHB field in a VA form instruction. */ | 514 | /* The SHB field in a VA form instruction. */ |
| 514 | #define SHB UIMM + 1 | 515 | #define SHB UIMM + 1 |
| 515 | { 4, 6, 0, 0, 0 }, | 516 | { 4, 6, NULL, NULL, 0 }, |
| 516 | 517 | ||
| 517 | /* The other UIMM field in a EVX form instruction. */ | 518 | /* The other UIMM field in a EVX form instruction. */ |
| 518 | #define EVUIMM SHB + 1 | 519 | #define EVUIMM SHB + 1 |
| 519 | { 5, 11, 0, 0, 0 }, | 520 | { 5, 11, NULL, NULL, 0 }, |
| 520 | 521 | ||
| 521 | /* The other UIMM field in a half word EVX form instruction. */ | 522 | /* The other UIMM field in a half word EVX form instruction. */ |
| 522 | #define EVUIMM_2 EVUIMM + 1 | 523 | #define EVUIMM_2 EVUIMM + 1 |
| @@ -533,11 +534,11 @@ const struct powerpc_operand powerpc_operands[] = | |||
| 533 | /* The WS field. */ | 534 | /* The WS field. */ |
| 534 | #define WS EVUIMM_8 + 1 | 535 | #define WS EVUIMM_8 + 1 |
| 535 | #define WS_MASK (0x7 << 11) | 536 | #define WS_MASK (0x7 << 11) |
| 536 | { 3, 11, 0, 0, 0 }, | 537 | { 3, 11, NULL, NULL, 0 }, |
| 537 | 538 | ||
| 538 | /* The L field in an mtmsrd instruction */ | 539 | /* The L field in an mtmsrd instruction */ |
| 539 | #define MTMSRD_L WS + 1 | 540 | #define MTMSRD_L WS + 1 |
| 540 | { 1, 16, 0, 0, PPC_OPERAND_OPTIONAL }, | 541 | { 1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL }, |
| 541 | 542 | ||
| 542 | }; | 543 | }; |
| 543 | 544 | ||
