diff options
Diffstat (limited to 'arch/x86')
77 files changed, 8142 insertions, 0 deletions
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c new file mode 100644 index 00000000000..89bbf4e4d05 --- /dev/null +++ b/arch/x86/boot/compressed/relocs.c | |||
| @@ -0,0 +1,682 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdarg.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <stdint.h> | ||
| 5 | #include <string.h> | ||
| 6 | #include <errno.h> | ||
| 7 | #include <unistd.h> | ||
| 8 | #include <elf.h> | ||
| 9 | #include <byteswap.h> | ||
| 10 | #define USE_BSD | ||
| 11 | #include <endian.h> | ||
| 12 | #include <regex.h> | ||
| 13 | |||
| 14 | static void die(char *fmt, ...); | ||
| 15 | |||
| 16 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
| 17 | static Elf32_Ehdr ehdr; | ||
| 18 | static unsigned long reloc_count, reloc_idx; | ||
| 19 | static unsigned long *relocs; | ||
| 20 | |||
| 21 | struct section { | ||
| 22 | Elf32_Shdr shdr; | ||
| 23 | struct section *link; | ||
| 24 | Elf32_Sym *symtab; | ||
| 25 | Elf32_Rel *reltab; | ||
| 26 | char *strtab; | ||
| 27 | }; | ||
| 28 | static struct section *secs; | ||
| 29 | |||
| 30 | /* | ||
| 31 | * Following symbols have been audited. There values are constant and do | ||
| 32 | * not change if bzImage is loaded at a different physical address than | ||
| 33 | * the address for which it has been compiled. Don't warn user about | ||
| 34 | * absolute relocations present w.r.t these symbols. | ||
| 35 | */ | ||
| 36 | static const char abs_sym_regex[] = | ||
| 37 | "^(xen_irq_disable_direct_reloc$|" | ||
| 38 | "xen_save_fl_direct_reloc$|" | ||
| 39 | "VDSO|" | ||
| 40 | "__crc_)"; | ||
| 41 | static regex_t abs_sym_regex_c; | ||
| 42 | static int is_abs_reloc(const char *sym_name) | ||
| 43 | { | ||
| 44 | return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); | ||
| 45 | } | ||
| 46 | |||
| 47 | /* | ||
| 48 | * These symbols are known to be relative, even if the linker marks them | ||
| 49 | * as absolute (typically defined outside any section in the linker script.) | ||
| 50 | */ | ||
| 51 | static const char rel_sym_regex[] = | ||
| 52 | "^_end$"; | ||
| 53 | static regex_t rel_sym_regex_c; | ||
| 54 | static int is_rel_reloc(const char *sym_name) | ||
| 55 | { | ||
| 56 | return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); | ||
| 57 | } | ||
| 58 | |||
| 59 | static void regex_init(void) | ||
| 60 | { | ||
| 61 | char errbuf[128]; | ||
| 62 | int err; | ||
| 63 | |||
| 64 | err = regcomp(&abs_sym_regex_c, abs_sym_regex, | ||
| 65 | REG_EXTENDED|REG_NOSUB); | ||
| 66 | if (err) { | ||
| 67 | regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); | ||
| 68 | die("%s", errbuf); | ||
| 69 | } | ||
| 70 | |||
| 71 | err = regcomp(&rel_sym_regex_c, rel_sym_regex, | ||
| 72 | REG_EXTENDED|REG_NOSUB); | ||
| 73 | if (err) { | ||
| 74 | regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); | ||
| 75 | die("%s", errbuf); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | static void die(char *fmt, ...) | ||
| 80 | { | ||
| 81 | va_list ap; | ||
| 82 | va_start(ap, fmt); | ||
| 83 | vfprintf(stderr, fmt, ap); | ||
| 84 | va_end(ap); | ||
| 85 | exit(1); | ||
| 86 | } | ||
| 87 | |||
| 88 | static const char *sym_type(unsigned type) | ||
| 89 | { | ||
| 90 | static const char *type_name[] = { | ||
| 91 | #define SYM_TYPE(X) [X] = #X | ||
| 92 | SYM_TYPE(STT_NOTYPE), | ||
| 93 | SYM_TYPE(STT_OBJECT), | ||
| 94 | SYM_TYPE(STT_FUNC), | ||
| 95 | SYM_TYPE(STT_SECTION), | ||
| 96 | SYM_TYPE(STT_FILE), | ||
| 97 | SYM_TYPE(STT_COMMON), | ||
| 98 | SYM_TYPE(STT_TLS), | ||
| 99 | #undef SYM_TYPE | ||
| 100 | }; | ||
| 101 | const char *name = "unknown sym type name"; | ||
| 102 | if (type < ARRAY_SIZE(type_name)) { | ||
| 103 | name = type_name[type]; | ||
| 104 | } | ||
| 105 | return name; | ||
| 106 | } | ||
| 107 | |||
| 108 | static const char *sym_bind(unsigned bind) | ||
| 109 | { | ||
| 110 | static const char *bind_name[] = { | ||
| 111 | #define SYM_BIND(X) [X] = #X | ||
| 112 | SYM_BIND(STB_LOCAL), | ||
| 113 | SYM_BIND(STB_GLOBAL), | ||
| 114 | SYM_BIND(STB_WEAK), | ||
| 115 | #undef SYM_BIND | ||
| 116 | }; | ||
| 117 | const char *name = "unknown sym bind name"; | ||
| 118 | if (bind < ARRAY_SIZE(bind_name)) { | ||
| 119 | name = bind_name[bind]; | ||
| 120 | } | ||
| 121 | return name; | ||
| 122 | } | ||
| 123 | |||
| 124 | static const char *sym_visibility(unsigned visibility) | ||
| 125 | { | ||
| 126 | static const char *visibility_name[] = { | ||
| 127 | #define SYM_VISIBILITY(X) [X] = #X | ||
| 128 | SYM_VISIBILITY(STV_DEFAULT), | ||
| 129 | SYM_VISIBILITY(STV_INTERNAL), | ||
| 130 | SYM_VISIBILITY(STV_HIDDEN), | ||
| 131 | SYM_VISIBILITY(STV_PROTECTED), | ||
| 132 | #undef SYM_VISIBILITY | ||
| 133 | }; | ||
| 134 | const char *name = "unknown sym visibility name"; | ||
| 135 | if (visibility < ARRAY_SIZE(visibility_name)) { | ||
| 136 | name = visibility_name[visibility]; | ||
| 137 | } | ||
| 138 | return name; | ||
| 139 | } | ||
| 140 | |||
| 141 | static const char *rel_type(unsigned type) | ||
| 142 | { | ||
| 143 | static const char *type_name[] = { | ||
| 144 | #define REL_TYPE(X) [X] = #X | ||
| 145 | REL_TYPE(R_386_NONE), | ||
| 146 | REL_TYPE(R_386_32), | ||
| 147 | REL_TYPE(R_386_PC32), | ||
| 148 | REL_TYPE(R_386_GOT32), | ||
| 149 | REL_TYPE(R_386_PLT32), | ||
| 150 | REL_TYPE(R_386_COPY), | ||
| 151 | REL_TYPE(R_386_GLOB_DAT), | ||
| 152 | REL_TYPE(R_386_JMP_SLOT), | ||
| 153 | REL_TYPE(R_386_RELATIVE), | ||
| 154 | REL_TYPE(R_386_GOTOFF), | ||
| 155 | REL_TYPE(R_386_GOTPC), | ||
| 156 | #undef REL_TYPE | ||
| 157 | }; | ||
| 158 | const char *name = "unknown type rel type name"; | ||
| 159 | if (type < ARRAY_SIZE(type_name) && type_name[type]) { | ||
| 160 | name = type_name[type]; | ||
| 161 | } | ||
| 162 | return name; | ||
| 163 | } | ||
| 164 | |||
| 165 | static const char *sec_name(unsigned shndx) | ||
| 166 | { | ||
| 167 | const char *sec_strtab; | ||
| 168 | const char *name; | ||
| 169 | sec_strtab = secs[ehdr.e_shstrndx].strtab; | ||
| 170 | name = "<noname>"; | ||
| 171 | if (shndx < ehdr.e_shnum) { | ||
| 172 | name = sec_strtab + secs[shndx].shdr.sh_name; | ||
| 173 | } | ||
| 174 | else if (shndx == SHN_ABS) { | ||
| 175 | name = "ABSOLUTE"; | ||
| 176 | } | ||
| 177 | else if (shndx == SHN_COMMON) { | ||
| 178 | name = "COMMON"; | ||
| 179 | } | ||
| 180 | return name; | ||
| 181 | } | ||
| 182 | |||
| 183 | static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym) | ||
| 184 | { | ||
| 185 | const char *name; | ||
| 186 | name = "<noname>"; | ||
| 187 | if (sym->st_name) { | ||
| 188 | name = sym_strtab + sym->st_name; | ||
| 189 | } | ||
| 190 | else { | ||
| 191 | name = sec_name(secs[sym->st_shndx].shdr.sh_name); | ||
| 192 | } | ||
| 193 | return name; | ||
| 194 | } | ||
| 195 | |||
| 196 | |||
| 197 | |||
| 198 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
| 199 | #define le16_to_cpu(val) (val) | ||
| 200 | #define le32_to_cpu(val) (val) | ||
| 201 | #endif | ||
| 202 | #if BYTE_ORDER == BIG_ENDIAN | ||
| 203 | #define le16_to_cpu(val) bswap_16(val) | ||
| 204 | #define le32_to_cpu(val) bswap_32(val) | ||
| 205 | #endif | ||
| 206 | |||
| 207 | static uint16_t elf16_to_cpu(uint16_t val) | ||
| 208 | { | ||
| 209 | return le16_to_cpu(val); | ||
| 210 | } | ||
| 211 | |||
| 212 | static uint32_t elf32_to_cpu(uint32_t val) | ||
| 213 | { | ||
| 214 | return le32_to_cpu(val); | ||
| 215 | } | ||
| 216 | |||
| 217 | static void read_ehdr(FILE *fp) | ||
| 218 | { | ||
| 219 | if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) { | ||
| 220 | die("Cannot read ELF header: %s\n", | ||
| 221 | strerror(errno)); | ||
| 222 | } | ||
| 223 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) { | ||
| 224 | die("No ELF magic\n"); | ||
| 225 | } | ||
| 226 | if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) { | ||
| 227 | die("Not a 32 bit executable\n"); | ||
| 228 | } | ||
| 229 | if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) { | ||
| 230 | die("Not a LSB ELF executable\n"); | ||
| 231 | } | ||
| 232 | if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) { | ||
| 233 | die("Unknown ELF version\n"); | ||
| 234 | } | ||
| 235 | /* Convert the fields to native endian */ | ||
| 236 | ehdr.e_type = elf16_to_cpu(ehdr.e_type); | ||
| 237 | ehdr.e_machine = elf16_to_cpu(ehdr.e_machine); | ||
| 238 | ehdr.e_version = elf32_to_cpu(ehdr.e_version); | ||
| 239 | ehdr.e_entry = elf32_to_cpu(ehdr.e_entry); | ||
| 240 | ehdr.e_phoff = elf32_to_cpu(ehdr.e_phoff); | ||
| 241 | ehdr.e_shoff = elf32_to_cpu(ehdr.e_shoff); | ||
| 242 | ehdr.e_flags = elf32_to_cpu(ehdr.e_flags); | ||
| 243 | ehdr.e_ehsize = elf16_to_cpu(ehdr.e_ehsize); | ||
| 244 | ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize); | ||
| 245 | ehdr.e_phnum = elf16_to_cpu(ehdr.e_phnum); | ||
| 246 | ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize); | ||
| 247 | ehdr.e_shnum = elf16_to_cpu(ehdr.e_shnum); | ||
| 248 | ehdr.e_shstrndx = elf16_to_cpu(ehdr.e_shstrndx); | ||
| 249 | |||
| 250 | if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) { | ||
| 251 | die("Unsupported ELF header type\n"); | ||
| 252 | } | ||
| 253 | if (ehdr.e_machine != EM_386) { | ||
| 254 | die("Not for x86\n"); | ||
| 255 | } | ||
| 256 | if (ehdr.e_version != EV_CURRENT) { | ||
| 257 | die("Unknown ELF version\n"); | ||
| 258 | } | ||
| 259 | if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) { | ||
| 260 | die("Bad Elf header size\n"); | ||
| 261 | } | ||
| 262 | if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) { | ||
| 263 | die("Bad program header entry\n"); | ||
| 264 | } | ||
| 265 | if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) { | ||
| 266 | die("Bad section header entry\n"); | ||
| 267 | } | ||
| 268 | if (ehdr.e_shstrndx >= ehdr.e_shnum) { | ||
| 269 | die("String table index out of bounds\n"); | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | static void read_shdrs(FILE *fp) | ||
| 274 | { | ||
| 275 | int i; | ||
| 276 | Elf32_Shdr shdr; | ||
| 277 | |||
| 278 | secs = calloc(ehdr.e_shnum, sizeof(struct section)); | ||
| 279 | if (!secs) { | ||
| 280 | die("Unable to allocate %d section headers\n", | ||
| 281 | ehdr.e_shnum); | ||
| 282 | } | ||
| 283 | if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) { | ||
| 284 | die("Seek to %d failed: %s\n", | ||
| 285 | ehdr.e_shoff, strerror(errno)); | ||
| 286 | } | ||
| 287 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
| 288 | struct section *sec = &secs[i]; | ||
| 289 | if (fread(&shdr, sizeof shdr, 1, fp) != 1) | ||
| 290 | die("Cannot read ELF section headers %d/%d: %s\n", | ||
| 291 | i, ehdr.e_shnum, strerror(errno)); | ||
| 292 | sec->shdr.sh_name = elf32_to_cpu(shdr.sh_name); | ||
| 293 | sec->shdr.sh_type = elf32_to_cpu(shdr.sh_type); | ||
| 294 | sec->shdr.sh_flags = elf32_to_cpu(shdr.sh_flags); | ||
| 295 | sec->shdr.sh_addr = elf32_to_cpu(shdr.sh_addr); | ||
| 296 | sec->shdr.sh_offset = elf32_to_cpu(shdr.sh_offset); | ||
| 297 | sec->shdr.sh_size = elf32_to_cpu(shdr.sh_size); | ||
| 298 | sec->shdr.sh_link = elf32_to_cpu(shdr.sh_link); | ||
| 299 | sec->shdr.sh_info = elf32_to_cpu(shdr.sh_info); | ||
| 300 | sec->shdr.sh_addralign = elf32_to_cpu(shdr.sh_addralign); | ||
| 301 | sec->shdr.sh_entsize = elf32_to_cpu(shdr.sh_entsize); | ||
| 302 | if (sec->shdr.sh_link < ehdr.e_shnum) | ||
| 303 | sec->link = &secs[sec->shdr.sh_link]; | ||
| 304 | } | ||
| 305 | |||
| 306 | } | ||
| 307 | |||
| 308 | static void read_strtabs(FILE *fp) | ||
| 309 | { | ||
| 310 | int i; | ||
| 311 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
| 312 | struct section *sec = &secs[i]; | ||
| 313 | if (sec->shdr.sh_type != SHT_STRTAB) { | ||
| 314 | continue; | ||
| 315 | } | ||
| 316 | sec->strtab = malloc(sec->shdr.sh_size); | ||
| 317 | if (!sec->strtab) { | ||
| 318 | die("malloc of %d bytes for strtab failed\n", | ||
| 319 | sec->shdr.sh_size); | ||
| 320 | } | ||
| 321 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { | ||
| 322 | die("Seek to %d failed: %s\n", | ||
| 323 | sec->shdr.sh_offset, strerror(errno)); | ||
| 324 | } | ||
| 325 | if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) | ||
| 326 | != sec->shdr.sh_size) { | ||
| 327 | die("Cannot read symbol table: %s\n", | ||
| 328 | strerror(errno)); | ||
| 329 | } | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | static void read_symtabs(FILE *fp) | ||
| 334 | { | ||
| 335 | int i,j; | ||
| 336 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
| 337 | struct section *sec = &secs[i]; | ||
| 338 | if (sec->shdr.sh_type != SHT_SYMTAB) { | ||
| 339 | continue; | ||
| 340 | } | ||
| 341 | sec->symtab = malloc(sec->shdr.sh_size); | ||
| 342 | if (!sec->symtab) { | ||
| 343 | die("malloc of %d bytes for symtab failed\n", | ||
| 344 | sec->shdr.sh_size); | ||
| 345 | } | ||
| 346 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { | ||
| 347 | die("Seek to %d failed: %s\n", | ||
| 348 | sec->shdr.sh_offset, strerror(errno)); | ||
| 349 | } | ||
| 350 | if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) | ||
| 351 | != sec->shdr.sh_size) { | ||
| 352 | die("Cannot read symbol table: %s\n", | ||
| 353 | strerror(errno)); | ||
| 354 | } | ||
| 355 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { | ||
| 356 | Elf32_Sym *sym = &sec->symtab[j]; | ||
| 357 | sym->st_name = elf32_to_cpu(sym->st_name); | ||
| 358 | sym->st_value = elf32_to_cpu(sym->st_value); | ||
| 359 | sym->st_size = elf32_to_cpu(sym->st_size); | ||
| 360 | sym->st_shndx = elf16_to_cpu(sym->st_shndx); | ||
| 361 | } | ||
| 362 | } | ||
| 363 | } | ||
| 364 | |||
| 365 | |||
| 366 | static void read_relocs(FILE *fp) | ||
| 367 | { | ||
| 368 | int i,j; | ||
| 369 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
| 370 | struct section *sec = &secs[i]; | ||
| 371 | if (sec->shdr.sh_type != SHT_REL) { | ||
| 372 | continue; | ||
| 373 | } | ||
| 374 | sec->reltab = malloc(sec->shdr.sh_size); | ||
| 375 | if (!sec->reltab) { | ||
| 376 | die("malloc of %d bytes for relocs failed\n", | ||
| 377 | sec->shdr.sh_size); | ||
| 378 | } | ||
| 379 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { | ||
| 380 | die("Seek to %d failed: %s\n", | ||
| 381 | sec->shdr.sh_offset, strerror(errno)); | ||
| 382 | } | ||
| 383 | if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) | ||
| 384 | != sec->shdr.sh_size) { | ||
| 385 | die("Cannot read symbol table: %s\n", | ||
| 386 | strerror(errno)); | ||
| 387 | } | ||
| 388 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { | ||
| 389 | Elf32_Rel *rel = &sec->reltab[j]; | ||
| 390 | rel->r_offset = elf32_to_cpu(rel->r_offset); | ||
| 391 | rel->r_info = elf32_to_cpu(rel->r_info); | ||
| 392 | } | ||
| 393 | } | ||
| 394 | } | ||
| 395 | |||
| 396 | |||
| 397 | static void print_absolute_symbols(void) | ||
| 398 | { | ||
| 399 | int i; | ||
| 400 | printf("Absolute symbols\n"); | ||
| 401 | printf(" Num: Value Size Type Bind Visibility Name\n"); | ||
| 402 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
| 403 | struct section *sec = &secs[i]; | ||
| 404 | char *sym_strtab; | ||
| 405 | Elf32_Sym *sh_symtab; | ||
| 406 | int j; | ||
| 407 | |||
| 408 | if (sec->shdr.sh_type != SHT_SYMTAB) { | ||
| 409 | continue; | ||
| 410 | } | ||
| 411 | sh_symtab = sec->symtab; | ||
| 412 | sym_strtab = sec->link->strtab; | ||
| 413 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { | ||
| 414 | Elf32_Sym *sym; | ||
| 415 | const char *name; | ||
| 416 | sym = &sec->symtab[j]; | ||
| 417 | name = sym_name(sym_strtab, sym); | ||
| 418 | if (sym->st_shndx != SHN_ABS) { | ||
| 419 | continue; | ||
| 420 | } | ||
| 421 | printf("%5d %08x %5d %10s %10s %12s %s\n", | ||
| 422 | j, sym->st_value, sym->st_size, | ||
| 423 | sym_type(ELF32_ST_TYPE(sym->st_info)), | ||
| 424 | sym_bind(ELF32_ST_BIND(sym->st_info)), | ||
| 425 | sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)), | ||
| 426 | name); | ||
| 427 | } | ||
| 428 | } | ||
| 429 | printf("\n"); | ||
| 430 | } | ||
| 431 | |||
| 432 | static void print_absolute_relocs(void) | ||
| 433 | { | ||
| 434 | int i, printed = 0; | ||
| 435 | |||
| 436 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
| 437 | struct section *sec = &secs[i]; | ||
| 438 | struct section *sec_applies, *sec_symtab; | ||
| 439 | char *sym_strtab; | ||
| 440 | Elf32_Sym *sh_symtab; | ||
| 441 | int j; | ||
| 442 | if (sec->shdr.sh_type != SHT_REL) { | ||
| 443 | continue; | ||
| 444 | } | ||
| 445 | sec_symtab = sec->link; | ||
| 446 | sec_applies = &secs[sec->shdr.sh_info]; | ||
| 447 | if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { | ||
| 448 | continue; | ||
| 449 | } | ||
| 450 | sh_symtab = sec_symtab->symtab; | ||
| 451 | sym_strtab = sec_symtab->link->strtab; | ||
| 452 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { | ||
| 453 | Elf32_Rel *rel; | ||
| 454 | Elf32_Sym *sym; | ||
| 455 | const char *name; | ||
| 456 | rel = &sec->reltab[j]; | ||
| 457 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; | ||
| 458 | name = sym_name(sym_strtab, sym); | ||
| 459 | if (sym->st_shndx != SHN_ABS) { | ||
| 460 | continue; | ||
| 461 | } | ||
| 462 | |||
| 463 | /* Absolute symbols are not relocated if bzImage is | ||
| 464 | * loaded at a non-compiled address. Display a warning | ||
| 465 | * to user at compile time about the absolute | ||
| 466 | * relocations present. | ||
| 467 | * | ||
| 468 | * User need to audit the code to make sure | ||
| 469 | * some symbols which should have been section | ||
| 470 | * relative have not become absolute because of some | ||
| 471 | * linker optimization or wrong programming usage. | ||
| 472 | * | ||
| 473 | * Before warning check if this absolute symbol | ||
| 474 | * relocation is harmless. | ||
| 475 | */ | ||
| 476 | if (is_abs_reloc(name) || is_rel_reloc(name)) | ||
| 477 | continue; | ||
| 478 | |||
| 479 | if (!printed) { | ||
| 480 | printf("WARNING: Absolute relocations" | ||
| 481 | " present\n"); | ||
| 482 | printf("Offset Info Type Sym.Value " | ||
| 483 | "Sym.Name\n"); | ||
| 484 | printed = 1; | ||
| 485 | } | ||
| 486 | |||
| 487 | printf("%08x %08x %10s %08x %s\n", | ||
| 488 | rel->r_offset, | ||
| 489 | rel->r_info, | ||
| 490 | rel_type(ELF32_R_TYPE(rel->r_info)), | ||
| 491 | sym->st_value, | ||
| 492 | name); | ||
| 493 | } | ||
| 494 | } | ||
| 495 | |||
| 496 | if (printed) | ||
| 497 | printf("\n"); | ||
| 498 | } | ||
| 499 | |||
| 500 | static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) | ||
| 501 | { | ||
| 502 | int i; | ||
| 503 | /* Walk through the relocations */ | ||
| 504 | for (i = 0; i < ehdr.e_shnum; i++) { | ||
| 505 | char *sym_strtab; | ||
| 506 | Elf32_Sym *sh_symtab; | ||
| 507 | struct section *sec_applies, *sec_symtab; | ||
| 508 | int j; | ||
| 509 | struct section *sec = &secs[i]; | ||
| 510 | |||
| 511 | if (sec->shdr.sh_type != SHT_REL) { | ||
| 512 | continue; | ||
| 513 | } | ||
| 514 | sec_symtab = sec->link; | ||
| 515 | sec_applies = &secs[sec->shdr.sh_info]; | ||
| 516 | if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { | ||
| 517 | continue; | ||
| 518 | } | ||
| 519 | sh_symtab = sec_symtab->symtab; | ||
| 520 | sym_strtab = sec_symtab->link->strtab; | ||
| 521 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { | ||
| 522 | Elf32_Rel *rel; | ||
| 523 | Elf32_Sym *sym; | ||
| 524 | unsigned r_type; | ||
| 525 | rel = &sec->reltab[j]; | ||
| 526 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; | ||
| 527 | r_type = ELF32_R_TYPE(rel->r_info); | ||
| 528 | /* Don't visit relocations to absolute symbols */ | ||
| 529 | if (sym->st_shndx == SHN_ABS && | ||
| 530 | !is_rel_reloc(sym_name(sym_strtab, sym))) { | ||
| 531 | continue; | ||
| 532 | } | ||
| 533 | switch (r_type) { | ||
| 534 | case R_386_NONE: | ||
| 535 | case R_386_PC32: | ||
| 536 | /* | ||
| 537 | * NONE can be ignored and and PC relative | ||
| 538 | * relocations don't need to be adjusted. | ||
| 539 | */ | ||
| 540 | break; | ||
| 541 | case R_386_32: | ||
| 542 | /* Visit relocations that need to be adjusted */ | ||
| 543 | visit(rel, sym); | ||
| 544 | break; | ||
| 545 | default: | ||
| 546 | die("Unsupported relocation type: %s (%d)\n", | ||
| 547 | rel_type(r_type), r_type); | ||
| 548 | break; | ||
| 549 | } | ||
| 550 | } | ||
| 551 | } | ||
| 552 | } | ||
| 553 | |||
| 554 | static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) | ||
| 555 | { | ||
| 556 | reloc_count += 1; | ||
| 557 | } | ||
| 558 | |||
| 559 | static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) | ||
| 560 | { | ||
| 561 | /* Remember the address that needs to be adjusted. */ | ||
| 562 | relocs[reloc_idx++] = rel->r_offset; | ||
| 563 | } | ||
| 564 | |||
| 565 | static int cmp_relocs(const void *va, const void *vb) | ||
| 566 | { | ||
| 567 | const unsigned long *a, *b; | ||
| 568 | a = va; b = vb; | ||
| 569 | return (*a == *b)? 0 : (*a > *b)? 1 : -1; | ||
| 570 | } | ||
| 571 | |||
| 572 | static void emit_relocs(int as_text) | ||
| 573 | { | ||
| 574 | int i; | ||
| 575 | /* Count how many relocations I have and allocate space for them. */ | ||
| 576 | reloc_count = 0; | ||
| 577 | walk_relocs(count_reloc); | ||
| 578 | relocs = malloc(reloc_count * sizeof(relocs[0])); | ||
| 579 | if (!relocs) { | ||
| 580 | die("malloc of %d entries for relocs failed\n", | ||
| 581 | reloc_count); | ||
| 582 | } | ||
| 583 | /* Collect up the relocations */ | ||
| 584 | reloc_idx = 0; | ||
| 585 | walk_relocs(collect_reloc); | ||
| 586 | |||
| 587 | /* Order the relocations for more efficient processing */ | ||
| 588 | qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); | ||
| 589 | |||
| 590 | /* Print the relocations */ | ||
| 591 | if (as_text) { | ||
| 592 | /* Print the relocations in a form suitable that | ||
| 593 | * gas will like. | ||
| 594 | */ | ||
| 595 | printf(".section \".data.reloc\",\"a\"\n"); | ||
| 596 | printf(".balign 4\n"); | ||
| 597 | for (i = 0; i < reloc_count; i++) { | ||
| 598 | printf("\t .long 0x%08lx\n", relocs[i]); | ||
| 599 | } | ||
| 600 | printf("\n"); | ||
| 601 | } | ||
| 602 | else { | ||
| 603 | unsigned char buf[4]; | ||
| 604 | /* Print a stop */ | ||
| 605 | fwrite("\0\0\0\0", 4, 1, stdout); | ||
| 606 | /* Now print each relocation */ | ||
| 607 | for (i = 0; i < reloc_count; i++) { | ||
| 608 | buf[0] = (relocs[i] >> 0) & 0xff; | ||
| 609 | buf[1] = (relocs[i] >> 8) & 0xff; | ||
| 610 | buf[2] = (relocs[i] >> 16) & 0xff; | ||
| 611 | buf[3] = (relocs[i] >> 24) & 0xff; | ||
| 612 | fwrite(buf, 4, 1, stdout); | ||
| 613 | } | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | static void usage(void) | ||
| 618 | { | ||
| 619 | die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); | ||
| 620 | } | ||
| 621 | |||
| 622 | int main(int argc, char **argv) | ||
| 623 | { | ||
| 624 | int show_absolute_syms, show_absolute_relocs; | ||
| 625 | int as_text; | ||
| 626 | const char *fname; | ||
| 627 | FILE *fp; | ||
| 628 | int i; | ||
| 629 | |||
| 630 | regex_init(); | ||
| 631 | |||
| 632 | show_absolute_syms = 0; | ||
| 633 | show_absolute_relocs = 0; | ||
| 634 | as_text = 0; | ||
| 635 | fname = NULL; | ||
| 636 | for (i = 1; i < argc; i++) { | ||
| 637 | char *arg = argv[i]; | ||
| 638 | if (*arg == '-') { | ||
| 639 | if (strcmp(argv[1], "--abs-syms") == 0) { | ||
| 640 | show_absolute_syms = 1; | ||
| 641 | continue; | ||
| 642 | } | ||
| 643 | |||
| 644 | if (strcmp(argv[1], "--abs-relocs") == 0) { | ||
| 645 | show_absolute_relocs = 1; | ||
| 646 | continue; | ||
| 647 | } | ||
| 648 | else if (strcmp(argv[1], "--text") == 0) { | ||
| 649 | as_text = 1; | ||
| 650 | continue; | ||
| 651 | } | ||
| 652 | } | ||
| 653 | else if (!fname) { | ||
| 654 | fname = arg; | ||
| 655 | continue; | ||
| 656 | } | ||
| 657 | usage(); | ||
| 658 | } | ||
| 659 | if (!fname) { | ||
| 660 | usage(); | ||
| 661 | } | ||
| 662 | fp = fopen(fname, "r"); | ||
| 663 | if (!fp) { | ||
| 664 | die("Cannot open %s: %s\n", | ||
| 665 | fname, strerror(errno)); | ||
| 666 | } | ||
| 667 | read_ehdr(fp); | ||
| 668 | read_shdrs(fp); | ||
| 669 | read_strtabs(fp); | ||
| 670 | read_symtabs(fp); | ||
| 671 | read_relocs(fp); | ||
| 672 | if (show_absolute_syms) { | ||
| 673 | print_absolute_symbols(); | ||
| 674 | return 0; | ||
| 675 | } | ||
| 676 | if (show_absolute_relocs) { | ||
| 677 | print_absolute_relocs(); | ||
| 678 | return 0; | ||
| 679 | } | ||
| 680 | emit_relocs(as_text); | ||
| 681 | return 0; | ||
| 682 | } | ||
diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c new file mode 100644 index 00000000000..b9d00261703 --- /dev/null +++ b/arch/x86/crypto/crc32c-intel.c | |||
| @@ -0,0 +1,198 @@ | |||
| 1 | /* | ||
| 2 | * Using hardware provided CRC32 instruction to accelerate the CRC32 disposal. | ||
| 3 | * CRC32C polynomial:0x1EDC6F41(BE)/0x82F63B78(LE) | ||
| 4 | * CRC32 is a new instruction in Intel SSE4.2, the reference can be found at: | ||
| 5 | * http://www.intel.com/products/processor/manuals/ | ||
| 6 | * Intel(R) 64 and IA-32 Architectures Software Developer's Manual | ||
| 7 | * Volume 2A: Instruction Set Reference, A-M | ||
| 8 | * | ||
| 9 | * Copyright (C) 2008 Intel Corporation | ||
| 10 | * Authors: Austin Zhang <austin_zhang@linux.intel.com> | ||
| 11 | * Kent Liu <kent.liu@intel.com> | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify it | ||
| 14 | * under the terms and conditions of the GNU General Public License, | ||
| 15 | * version 2, as published by the Free Software Foundation. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 19 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 20 | * more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License along with | ||
| 23 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 24 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/string.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <crypto/internal/hash.h> | ||
| 32 | |||
| 33 | #include <asm/cpufeature.h> | ||
| 34 | |||
| 35 | #define CHKSUM_BLOCK_SIZE 1 | ||
| 36 | #define CHKSUM_DIGEST_SIZE 4 | ||
| 37 | |||
| 38 | #define SCALE_F sizeof(unsigned long) | ||
| 39 | |||
| 40 | #ifdef CONFIG_X86_64 | ||
| 41 | #define REX_PRE "0x48, " | ||
| 42 | #else | ||
| 43 | #define REX_PRE | ||
| 44 | #endif | ||
| 45 | |||
| 46 | static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length) | ||
| 47 | { | ||
| 48 | while (length--) { | ||
| 49 | __asm__ __volatile__( | ||
| 50 | ".byte 0xf2, 0xf, 0x38, 0xf0, 0xf1" | ||
| 51 | :"=S"(crc) | ||
| 52 | :"0"(crc), "c"(*data) | ||
| 53 | ); | ||
| 54 | data++; | ||
| 55 | } | ||
| 56 | |||
| 57 | return crc; | ||
| 58 | } | ||
| 59 | |||
| 60 | static u32 __pure crc32c_intel_le_hw(u32 crc, unsigned char const *p, size_t len) | ||
| 61 | { | ||
| 62 | unsigned int iquotient = len / SCALE_F; | ||
| 63 | unsigned int iremainder = len % SCALE_F; | ||
| 64 | unsigned long *ptmp = (unsigned long *)p; | ||
| 65 | |||
| 66 | while (iquotient--) { | ||
| 67 | __asm__ __volatile__( | ||
| 68 | ".byte 0xf2, " REX_PRE "0xf, 0x38, 0xf1, 0xf1;" | ||
| 69 | :"=S"(crc) | ||
| 70 | :"0"(crc), "c"(*ptmp) | ||
| 71 | ); | ||
| 72 | ptmp++; | ||
| 73 | } | ||
| 74 | |||
| 75 | if (iremainder) | ||
| 76 | crc = crc32c_intel_le_hw_byte(crc, (unsigned char *)ptmp, | ||
| 77 | iremainder); | ||
| 78 | |||
| 79 | return crc; | ||
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Setting the seed allows arbitrary accumulators and flexible XOR policy | ||
| 84 | * If your algorithm starts with ~0, then XOR with ~0 before you set | ||
| 85 | * the seed. | ||
| 86 | */ | ||
| 87 | static int crc32c_intel_setkey(struct crypto_shash *hash, const u8 *key, | ||
| 88 | unsigned int keylen) | ||
| 89 | { | ||
| 90 | u32 *mctx = crypto_shash_ctx(hash); | ||
| 91 | |||
| 92 | if (keylen != sizeof(u32)) { | ||
| 93 | crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
| 94 | return -EINVAL; | ||
| 95 | } | ||
| 96 | *mctx = le32_to_cpup((__le32 *)key); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | static int crc32c_intel_init(struct shash_desc *desc) | ||
| 101 | { | ||
| 102 | u32 *mctx = crypto_shash_ctx(desc->tfm); | ||
| 103 | u32 *crcp = shash_desc_ctx(desc); | ||
| 104 | |||
| 105 | *crcp = *mctx; | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int crc32c_intel_update(struct shash_desc *desc, const u8 *data, | ||
| 111 | unsigned int len) | ||
| 112 | { | ||
| 113 | u32 *crcp = shash_desc_ctx(desc); | ||
| 114 | |||
| 115 | *crcp = crc32c_intel_le_hw(*crcp, data, len); | ||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | static int __crc32c_intel_finup(u32 *crcp, const u8 *data, unsigned int len, | ||
| 120 | u8 *out) | ||
| 121 | { | ||
| 122 | *(__le32 *)out = ~cpu_to_le32(crc32c_intel_le_hw(*crcp, data, len)); | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static int crc32c_intel_finup(struct shash_desc *desc, const u8 *data, | ||
| 127 | unsigned int len, u8 *out) | ||
| 128 | { | ||
| 129 | return __crc32c_intel_finup(shash_desc_ctx(desc), data, len, out); | ||
| 130 | } | ||
| 131 | |||
| 132 | static int crc32c_intel_final(struct shash_desc *desc, u8 *out) | ||
| 133 | { | ||
| 134 | u32 *crcp = shash_desc_ctx(desc); | ||
| 135 | |||
| 136 | *(__le32 *)out = ~cpu_to_le32p(crcp); | ||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | static int crc32c_intel_digest(struct shash_desc *desc, const u8 *data, | ||
| 141 | unsigned int len, u8 *out) | ||
| 142 | { | ||
| 143 | return __crc32c_intel_finup(crypto_shash_ctx(desc->tfm), data, len, | ||
| 144 | out); | ||
| 145 | } | ||
| 146 | |||
| 147 | static int crc32c_intel_cra_init(struct crypto_tfm *tfm) | ||
| 148 | { | ||
| 149 | u32 *key = crypto_tfm_ctx(tfm); | ||
| 150 | |||
| 151 | *key = ~0; | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | static struct shash_alg alg = { | ||
| 157 | .setkey = crc32c_intel_setkey, | ||
| 158 | .init = crc32c_intel_init, | ||
| 159 | .update = crc32c_intel_update, | ||
| 160 | .final = crc32c_intel_final, | ||
| 161 | .finup = crc32c_intel_finup, | ||
| 162 | .digest = crc32c_intel_digest, | ||
| 163 | .descsize = sizeof(u32), | ||
| 164 | .digestsize = CHKSUM_DIGEST_SIZE, | ||
| 165 | .base = { | ||
| 166 | .cra_name = "crc32c", | ||
| 167 | .cra_driver_name = "crc32c-intel", | ||
| 168 | .cra_priority = 200, | ||
| 169 | .cra_blocksize = CHKSUM_BLOCK_SIZE, | ||
| 170 | .cra_ctxsize = sizeof(u32), | ||
| 171 | .cra_module = THIS_MODULE, | ||
| 172 | .cra_init = crc32c_intel_cra_init, | ||
| 173 | } | ||
| 174 | }; | ||
| 175 | |||
| 176 | |||
| 177 | static int __init crc32c_intel_mod_init(void) | ||
| 178 | { | ||
| 179 | if (cpu_has_xmm4_2) | ||
| 180 | return crypto_register_shash(&alg); | ||
| 181 | else | ||
| 182 | return -ENODEV; | ||
| 183 | } | ||
| 184 | |||
| 185 | static void __exit crc32c_intel_mod_fini(void) | ||
| 186 | { | ||
| 187 | crypto_unregister_shash(&alg); | ||
| 188 | } | ||
| 189 | |||
| 190 | module_init(crc32c_intel_mod_init); | ||
| 191 | module_exit(crc32c_intel_mod_fini); | ||
| 192 | |||
| 193 | MODULE_AUTHOR("Austin Zhang <austin.zhang@intel.com>, Kent Liu <kent.liu@intel.com>"); | ||
| 194 | MODULE_DESCRIPTION("CRC32c (Castagnoli) optimization using Intel Hardware."); | ||
| 195 | MODULE_LICENSE("GPL"); | ||
| 196 | |||
| 197 | MODULE_ALIAS("crc32c"); | ||
| 198 | MODULE_ALIAS("crc32c-intel"); | ||
diff --git a/arch/x86/include/asm/a.out.h b/arch/x86/include/asm/a.out.h new file mode 100644 index 00000000000..4684f97a5bb --- /dev/null +++ b/arch/x86/include/asm/a.out.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #ifndef _ASM_X86_A_OUT_H | ||
| 2 | #define _ASM_X86_A_OUT_H | ||
| 3 | |||
| 4 | struct exec | ||
| 5 | { | ||
| 6 | unsigned int a_info; /* Use macros N_MAGIC, etc for access */ | ||
| 7 | unsigned a_text; /* length of text, in bytes */ | ||
| 8 | unsigned a_data; /* length of data, in bytes */ | ||
| 9 | unsigned a_bss; /* length of uninitialized data area for file, in bytes */ | ||
| 10 | unsigned a_syms; /* length of symbol table data in file, in bytes */ | ||
| 11 | unsigned a_entry; /* start address */ | ||
| 12 | unsigned a_trsize; /* length of relocation info for text, in bytes */ | ||
| 13 | unsigned a_drsize; /* length of relocation info for data, in bytes */ | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define N_TRSIZE(a) ((a).a_trsize) | ||
| 17 | #define N_DRSIZE(a) ((a).a_drsize) | ||
| 18 | #define N_SYMSIZE(a) ((a).a_syms) | ||
| 19 | |||
| 20 | #endif /* _ASM_X86_A_OUT_H */ | ||
diff --git a/arch/x86/include/asm/aes.h b/arch/x86/include/asm/aes.h new file mode 100644 index 00000000000..80545a1cbe3 --- /dev/null +++ b/arch/x86/include/asm/aes.h | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | #ifndef ASM_X86_AES_H | ||
| 2 | #define ASM_X86_AES_H | ||
| 3 | |||
| 4 | #include <linux/crypto.h> | ||
| 5 | #include <crypto/aes.h> | ||
| 6 | |||
| 7 | void crypto_aes_encrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, | ||
| 8 | const u8 *src); | ||
| 9 | void crypto_aes_decrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, | ||
| 10 | const u8 *src); | ||
| 11 | #endif | ||
diff --git a/arch/x86/include/asm/auxvec.h b/arch/x86/include/asm/auxvec.h new file mode 100644 index 00000000000..1316b4c3542 --- /dev/null +++ b/arch/x86/include/asm/auxvec.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef _ASM_X86_AUXVEC_H | ||
| 2 | #define _ASM_X86_AUXVEC_H | ||
| 3 | /* | ||
| 4 | * Architecture-neutral AT_ values in 0-17, leave some room | ||
| 5 | * for more of them, start the x86-specific ones at 32. | ||
| 6 | */ | ||
| 7 | #ifdef __i386__ | ||
| 8 | #define AT_SYSINFO 32 | ||
| 9 | #endif | ||
| 10 | #define AT_SYSINFO_EHDR 33 | ||
| 11 | |||
| 12 | #endif /* _ASM_X86_AUXVEC_H */ | ||
diff --git a/arch/x86/include/asm/bitsperlong.h b/arch/x86/include/asm/bitsperlong.h new file mode 100644 index 00000000000..b0ae1c4dc79 --- /dev/null +++ b/arch/x86/include/asm/bitsperlong.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | #ifndef __ASM_X86_BITSPERLONG_H | ||
| 2 | #define __ASM_X86_BITSPERLONG_H | ||
| 3 | |||
| 4 | #ifdef __x86_64__ | ||
| 5 | # define __BITS_PER_LONG 64 | ||
| 6 | #else | ||
| 7 | # define __BITS_PER_LONG 32 | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #include <asm-generic/bitsperlong.h> | ||
| 11 | |||
| 12 | #endif /* __ASM_X86_BITSPERLONG_H */ | ||
| 13 | |||
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h new file mode 100644 index 00000000000..e020d88ec02 --- /dev/null +++ b/arch/x86/include/asm/bootparam.h | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | #ifndef _ASM_X86_BOOTPARAM_H | ||
| 2 | #define _ASM_X86_BOOTPARAM_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | #include <linux/screen_info.h> | ||
| 6 | #include <linux/apm_bios.h> | ||
| 7 | #include <linux/edd.h> | ||
| 8 | #include <asm/e820.h> | ||
| 9 | #include <asm/ist.h> | ||
| 10 | #include <video/edid.h> | ||
| 11 | |||
| 12 | /* setup data types */ | ||
| 13 | #define SETUP_NONE 0 | ||
| 14 | #define SETUP_E820_EXT 1 | ||
| 15 | #define SETUP_DTB 2 | ||
| 16 | |||
| 17 | /* extensible setup data list node */ | ||
| 18 | struct setup_data { | ||
| 19 | __u64 next; | ||
| 20 | __u32 type; | ||
| 21 | __u32 len; | ||
| 22 | __u8 data[0]; | ||
| 23 | }; | ||
| 24 | |||
| 25 | struct setup_header { | ||
| 26 | __u8 setup_sects; | ||
| 27 | __u16 root_flags; | ||
| 28 | __u32 syssize; | ||
| 29 | __u16 ram_size; | ||
| 30 | #define RAMDISK_IMAGE_START_MASK 0x07FF | ||
| 31 | #define RAMDISK_PROMPT_FLAG 0x8000 | ||
| 32 | #define RAMDISK_LOAD_FLAG 0x4000 | ||
| 33 | __u16 vid_mode; | ||
| 34 | __u16 root_dev; | ||
| 35 | __u16 boot_flag; | ||
| 36 | __u16 jump; | ||
| 37 | __u32 header; | ||
| 38 | __u16 version; | ||
| 39 | __u32 realmode_swtch; | ||
| 40 | __u16 start_sys; | ||
| 41 | __u16 kernel_version; | ||
| 42 | __u8 type_of_loader; | ||
| 43 | __u8 loadflags; | ||
| 44 | #define LOADED_HIGH (1<<0) | ||
| 45 | #define QUIET_FLAG (1<<5) | ||
| 46 | #define KEEP_SEGMENTS (1<<6) | ||
| 47 | #define CAN_USE_HEAP (1<<7) | ||
| 48 | __u16 setup_move_size; | ||
| 49 | __u32 code32_start; | ||
| 50 | __u32 ramdisk_image; | ||
| 51 | __u32 ramdisk_size; | ||
| 52 | __u32 bootsect_kludge; | ||
| 53 | __u16 heap_end_ptr; | ||
| 54 | __u8 ext_loader_ver; | ||
| 55 | __u8 ext_loader_type; | ||
| 56 | __u32 cmd_line_ptr; | ||
| 57 | __u32 initrd_addr_max; | ||
| 58 | __u32 kernel_alignment; | ||
| 59 | __u8 relocatable_kernel; | ||
| 60 | __u8 _pad2[3]; | ||
| 61 | __u32 cmdline_size; | ||
| 62 | __u32 hardware_subarch; | ||
| 63 | __u64 hardware_subarch_data; | ||
| 64 | __u32 payload_offset; | ||
| 65 | __u32 payload_length; | ||
| 66 | __u64 setup_data; | ||
| 67 | } __attribute__((packed)); | ||
| 68 | |||
| 69 | struct sys_desc_table { | ||
| 70 | __u16 length; | ||
| 71 | __u8 table[14]; | ||
| 72 | }; | ||
| 73 | |||
| 74 | /* Gleaned from OFW's set-parameters in cpu/x86/pc/linux.fth */ | ||
| 75 | struct olpc_ofw_header { | ||
| 76 | __u32 ofw_magic; /* OFW signature */ | ||
| 77 | __u32 ofw_version; | ||
| 78 | __u32 cif_handler; /* callback into OFW */ | ||
| 79 | __u32 irq_desc_table; | ||
| 80 | } __attribute__((packed)); | ||
| 81 | |||
| 82 | struct efi_info { | ||
| 83 | __u32 efi_loader_signature; | ||
| 84 | __u32 efi_systab; | ||
| 85 | __u32 efi_memdesc_size; | ||
| 86 | __u32 efi_memdesc_version; | ||
| 87 | __u32 efi_memmap; | ||
| 88 | __u32 efi_memmap_size; | ||
| 89 | __u32 efi_systab_hi; | ||
| 90 | __u32 efi_memmap_hi; | ||
| 91 | }; | ||
| 92 | |||
| 93 | /* The so-called "zeropage" */ | ||
| 94 | struct boot_params { | ||
| 95 | struct screen_info screen_info; /* 0x000 */ | ||
| 96 | struct apm_bios_info apm_bios_info; /* 0x040 */ | ||
| 97 | __u8 _pad2[4]; /* 0x054 */ | ||
| 98 | __u64 tboot_addr; /* 0x058 */ | ||
| 99 | struct ist_info ist_info; /* 0x060 */ | ||
| 100 | __u8 _pad3[16]; /* 0x070 */ | ||
| 101 | __u8 hd0_info[16]; /* obsolete! */ /* 0x080 */ | ||
| 102 | __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */ | ||
| 103 | struct sys_desc_table sys_desc_table; /* 0x0a0 */ | ||
| 104 | struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */ | ||
| 105 | __u8 _pad4[128]; /* 0x0c0 */ | ||
| 106 | struct edid_info edid_info; /* 0x140 */ | ||
| 107 | struct efi_info efi_info; /* 0x1c0 */ | ||
| 108 | __u32 alt_mem_k; /* 0x1e0 */ | ||
| 109 | __u32 scratch; /* Scratch field! */ /* 0x1e4 */ | ||
| 110 | __u8 e820_entries; /* 0x1e8 */ | ||
| 111 | __u8 eddbuf_entries; /* 0x1e9 */ | ||
| 112 | __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ | ||
| 113 | __u8 _pad6[6]; /* 0x1eb */ | ||
| 114 | struct setup_header hdr; /* setup header */ /* 0x1f1 */ | ||
| 115 | __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; | ||
| 116 | __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ | ||
| 117 | struct e820entry e820_map[E820MAX]; /* 0x2d0 */ | ||
| 118 | __u8 _pad8[48]; /* 0xcd0 */ | ||
| 119 | struct edd_info eddbuf[EDDMAXNR]; /* 0xd00 */ | ||
| 120 | __u8 _pad9[276]; /* 0xeec */ | ||
| 121 | } __attribute__((packed)); | ||
| 122 | |||
| 123 | enum { | ||
| 124 | X86_SUBARCH_PC = 0, | ||
| 125 | X86_SUBARCH_LGUEST, | ||
| 126 | X86_SUBARCH_XEN, | ||
| 127 | X86_SUBARCH_MRST, | ||
| 128 | X86_SUBARCH_CE4100, | ||
| 129 | X86_NR_SUBARCHS, | ||
| 130 | }; | ||
| 131 | |||
| 132 | |||
| 133 | |||
| 134 | #endif /* _ASM_X86_BOOTPARAM_H */ | ||
diff --git a/arch/x86/include/asm/byteorder.h b/arch/x86/include/asm/byteorder.h new file mode 100644 index 00000000000..b13a7a88f3e --- /dev/null +++ b/arch/x86/include/asm/byteorder.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef _ASM_X86_BYTEORDER_H | ||
| 2 | #define _ASM_X86_BYTEORDER_H | ||
| 3 | |||
| 4 | #include <linux/byteorder/little_endian.h> | ||
| 5 | |||
| 6 | #endif /* _ASM_X86_BYTEORDER_H */ | ||
diff --git a/arch/x86/include/asm/errno.h b/arch/x86/include/asm/errno.h new file mode 100644 index 00000000000..4c82b503d92 --- /dev/null +++ b/arch/x86/include/asm/errno.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/errno.h> | |||
diff --git a/arch/x86/include/asm/fcntl.h b/arch/x86/include/asm/fcntl.h new file mode 100644 index 00000000000..46ab12db573 --- /dev/null +++ b/arch/x86/include/asm/fcntl.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/fcntl.h> | |||
diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h new file mode 100644 index 00000000000..5df477ac3af --- /dev/null +++ b/arch/x86/include/asm/hyperv.h | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | #ifndef _ASM_X86_HYPERV_H | ||
| 2 | #define _ASM_X86_HYPERV_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent | ||
| 8 | * is set by CPUID(HvCpuIdFunctionVersionAndFeatures). | ||
| 9 | */ | ||
| 10 | #define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS 0x40000000 | ||
| 11 | #define HYPERV_CPUID_INTERFACE 0x40000001 | ||
| 12 | #define HYPERV_CPUID_VERSION 0x40000002 | ||
| 13 | #define HYPERV_CPUID_FEATURES 0x40000003 | ||
| 14 | #define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004 | ||
| 15 | #define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005 | ||
| 16 | |||
| 17 | #define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000 | ||
| 18 | #define HYPERV_CPUID_MIN 0x40000005 | ||
| 19 | #define HYPERV_CPUID_MAX 0x4000ffff | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Feature identification. EAX indicates which features are available | ||
| 23 | * to the partition based upon the current partition privileges. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */ | ||
| 27 | #define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0) | ||
| 28 | /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ | ||
| 29 | #define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) | ||
| 30 | /* | ||
| 31 | * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM | ||
| 32 | * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available | ||
| 33 | */ | ||
| 34 | #define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2) | ||
| 35 | /* | ||
| 36 | * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through | ||
| 37 | * HV_X64_MSR_STIMER3_COUNT) available | ||
| 38 | */ | ||
| 39 | #define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3) | ||
| 40 | /* | ||
| 41 | * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) | ||
| 42 | * are available | ||
| 43 | */ | ||
| 44 | #define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4) | ||
| 45 | /* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/ | ||
| 46 | #define HV_X64_MSR_HYPERCALL_AVAILABLE (1 << 5) | ||
| 47 | /* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/ | ||
| 48 | #define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6) | ||
| 49 | /* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/ | ||
| 50 | #define HV_X64_MSR_RESET_AVAILABLE (1 << 7) | ||
| 51 | /* | ||
| 52 | * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE, | ||
| 53 | * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE, | ||
| 54 | * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available | ||
| 55 | */ | ||
| 56 | #define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Feature identification: EBX indicates which flags were specified at | ||
| 60 | * partition creation. The format is the same as the partition creation | ||
| 61 | * flag structure defined in section Partition Creation Flags. | ||
| 62 | */ | ||
| 63 | #define HV_X64_CREATE_PARTITIONS (1 << 0) | ||
| 64 | #define HV_X64_ACCESS_PARTITION_ID (1 << 1) | ||
| 65 | #define HV_X64_ACCESS_MEMORY_POOL (1 << 2) | ||
| 66 | #define HV_X64_ADJUST_MESSAGE_BUFFERS (1 << 3) | ||
| 67 | #define HV_X64_POST_MESSAGES (1 << 4) | ||
| 68 | #define HV_X64_SIGNAL_EVENTS (1 << 5) | ||
| 69 | #define HV_X64_CREATE_PORT (1 << 6) | ||
| 70 | #define HV_X64_CONNECT_PORT (1 << 7) | ||
| 71 | #define HV_X64_ACCESS_STATS (1 << 8) | ||
| 72 | #define HV_X64_DEBUGGING (1 << 11) | ||
| 73 | #define HV_X64_CPU_POWER_MANAGEMENT (1 << 12) | ||
| 74 | #define HV_X64_CONFIGURE_PROFILER (1 << 13) | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Feature identification. EDX indicates which miscellaneous features | ||
| 78 | * are available to the partition. | ||
| 79 | */ | ||
| 80 | /* The MWAIT instruction is available (per section MONITOR / MWAIT) */ | ||
| 81 | #define HV_X64_MWAIT_AVAILABLE (1 << 0) | ||
| 82 | /* Guest debugging support is available */ | ||
| 83 | #define HV_X64_GUEST_DEBUGGING_AVAILABLE (1 << 1) | ||
| 84 | /* Performance Monitor support is available*/ | ||
| 85 | #define HV_X64_PERF_MONITOR_AVAILABLE (1 << 2) | ||
| 86 | /* Support for physical CPU dynamic partitioning events is available*/ | ||
| 87 | #define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE (1 << 3) | ||
| 88 | /* | ||
| 89 | * Support for passing hypercall input parameter block via XMM | ||
| 90 | * registers is available | ||
| 91 | */ | ||
| 92 | #define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE (1 << 4) | ||
| 93 | /* Support for a virtual guest idle state is available */ | ||
| 94 | #define HV_X64_GUEST_IDLE_STATE_AVAILABLE (1 << 5) | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Implementation recommendations. Indicates which behaviors the hypervisor | ||
| 98 | * recommends the OS implement for optimal performance. | ||
| 99 | */ | ||
| 100 | /* | ||
| 101 | * Recommend using hypercall for address space switches rather | ||
| 102 | * than MOV to CR3 instruction | ||
| 103 | */ | ||
| 104 | #define HV_X64_MWAIT_RECOMMENDED (1 << 0) | ||
| 105 | /* Recommend using hypercall for local TLB flushes rather | ||
| 106 | * than INVLPG or MOV to CR3 instructions */ | ||
| 107 | #define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED (1 << 1) | ||
| 108 | /* | ||
| 109 | * Recommend using hypercall for remote TLB flushes rather | ||
| 110 | * than inter-processor interrupts | ||
| 111 | */ | ||
| 112 | #define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED (1 << 2) | ||
| 113 | /* | ||
| 114 | * Recommend using MSRs for accessing APIC registers | ||
| 115 | * EOI, ICR and TPR rather than their memory-mapped counterparts | ||
| 116 | */ | ||
| 117 | #define HV_X64_APIC_ACCESS_RECOMMENDED (1 << 3) | ||
| 118 | /* Recommend using the hypervisor-provided MSR to initiate a system RESET */ | ||
| 119 | #define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4) | ||
| 120 | /* | ||
| 121 | * Recommend using relaxed timing for this partition. If used, | ||
| 122 | * the VM should disable any watchdog timeouts that rely on the | ||
| 123 | * timely delivery of external interrupts | ||
| 124 | */ | ||
| 125 | #define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5) | ||
| 126 | |||
| 127 | /* MSR used to identify the guest OS. */ | ||
| 128 | #define HV_X64_MSR_GUEST_OS_ID 0x40000000 | ||
| 129 | |||
| 130 | /* MSR used to setup pages used to communicate with the hypervisor. */ | ||
| 131 | #define HV_X64_MSR_HYPERCALL 0x40000001 | ||
| 132 | |||
| 133 | /* MSR used to provide vcpu index */ | ||
| 134 | #define HV_X64_MSR_VP_INDEX 0x40000002 | ||
| 135 | |||
| 136 | /* MSR used to read the per-partition time reference counter */ | ||
| 137 | #define HV_X64_MSR_TIME_REF_COUNT 0x40000020 | ||
| 138 | |||
| 139 | /* Define the virtual APIC registers */ | ||
| 140 | #define HV_X64_MSR_EOI 0x40000070 | ||
| 141 | #define HV_X64_MSR_ICR 0x40000071 | ||
| 142 | #define HV_X64_MSR_TPR 0x40000072 | ||
| 143 | #define HV_X64_MSR_APIC_ASSIST_PAGE 0x40000073 | ||
| 144 | |||
| 145 | /* Define synthetic interrupt controller model specific registers. */ | ||
| 146 | #define HV_X64_MSR_SCONTROL 0x40000080 | ||
| 147 | #define HV_X64_MSR_SVERSION 0x40000081 | ||
| 148 | #define HV_X64_MSR_SIEFP 0x40000082 | ||
| 149 | #define HV_X64_MSR_SIMP 0x40000083 | ||
| 150 | #define HV_X64_MSR_EOM 0x40000084 | ||
| 151 | #define HV_X64_MSR_SINT0 0x40000090 | ||
| 152 | #define HV_X64_MSR_SINT1 0x40000091 | ||
| 153 | #define HV_X64_MSR_SINT2 0x40000092 | ||
| 154 | #define HV_X64_MSR_SINT3 0x40000093 | ||
| 155 | #define HV_X64_MSR_SINT4 0x40000094 | ||
| 156 | #define HV_X64_MSR_SINT5 0x40000095 | ||
| 157 | #define HV_X64_MSR_SINT6 0x40000096 | ||
| 158 | #define HV_X64_MSR_SINT7 0x40000097 | ||
| 159 | #define HV_X64_MSR_SINT8 0x40000098 | ||
| 160 | #define HV_X64_MSR_SINT9 0x40000099 | ||
| 161 | #define HV_X64_MSR_SINT10 0x4000009A | ||
| 162 | #define HV_X64_MSR_SINT11 0x4000009B | ||
| 163 | #define HV_X64_MSR_SINT12 0x4000009C | ||
| 164 | #define HV_X64_MSR_SINT13 0x4000009D | ||
| 165 | #define HV_X64_MSR_SINT14 0x4000009E | ||
| 166 | #define HV_X64_MSR_SINT15 0x4000009F | ||
| 167 | |||
| 168 | |||
| 169 | #define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001 | ||
| 170 | #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12 | ||
| 171 | #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \ | ||
| 172 | (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1)) | ||
| 173 | |||
| 174 | /* Declare the various hypercall operations. */ | ||
| 175 | #define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT 0x0008 | ||
| 176 | |||
| 177 | #define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001 | ||
| 178 | #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12 | ||
| 179 | #define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK \ | ||
| 180 | (~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1)) | ||
| 181 | |||
| 182 | #define HV_PROCESSOR_POWER_STATE_C0 0 | ||
| 183 | #define HV_PROCESSOR_POWER_STATE_C1 1 | ||
| 184 | #define HV_PROCESSOR_POWER_STATE_C2 2 | ||
| 185 | #define HV_PROCESSOR_POWER_STATE_C3 3 | ||
| 186 | |||
| 187 | /* hypercall status code */ | ||
| 188 | #define HV_STATUS_SUCCESS 0 | ||
| 189 | #define HV_STATUS_INVALID_HYPERCALL_CODE 2 | ||
| 190 | #define HV_STATUS_INVALID_HYPERCALL_INPUT 3 | ||
| 191 | #define HV_STATUS_INVALID_ALIGNMENT 4 | ||
| 192 | |||
| 193 | #endif | ||
diff --git a/arch/x86/include/asm/ioctl.h b/arch/x86/include/asm/ioctl.h new file mode 100644 index 00000000000..b279fe06dfe --- /dev/null +++ b/arch/x86/include/asm/ioctl.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/ioctl.h> | |||
diff --git a/arch/x86/include/asm/ioctls.h b/arch/x86/include/asm/ioctls.h new file mode 100644 index 00000000000..ec34c760665 --- /dev/null +++ b/arch/x86/include/asm/ioctls.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/ioctls.h> | |||
diff --git a/arch/x86/include/asm/ipcbuf.h b/arch/x86/include/asm/ipcbuf.h new file mode 100644 index 00000000000..84c7e51cb6d --- /dev/null +++ b/arch/x86/include/asm/ipcbuf.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/ipcbuf.h> | |||
diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h new file mode 100644 index 00000000000..423bbbddf36 --- /dev/null +++ b/arch/x86/include/asm/irq_controller.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef __IRQ_CONTROLLER__ | ||
| 2 | #define __IRQ_CONTROLLER__ | ||
| 3 | |||
| 4 | struct irq_domain { | ||
| 5 | int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize, | ||
| 6 | u32 *out_hwirq, u32 *out_type); | ||
| 7 | void *priv; | ||
| 8 | struct device_node *controller; | ||
| 9 | struct list_head l; | ||
| 10 | }; | ||
| 11 | |||
| 12 | #endif | ||
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h new file mode 100644 index 00000000000..4d8dcbdfc12 --- /dev/null +++ b/arch/x86/include/asm/kvm.h | |||
| @@ -0,0 +1,324 @@ | |||
| 1 | #ifndef _ASM_X86_KVM_H | ||
| 2 | #define _ASM_X86_KVM_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * KVM x86 specific structures and definitions | ||
| 6 | * | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/types.h> | ||
| 10 | #include <linux/ioctl.h> | ||
| 11 | |||
| 12 | /* Select x86 specific features in <linux/kvm.h> */ | ||
| 13 | #define __KVM_HAVE_PIT | ||
| 14 | #define __KVM_HAVE_IOAPIC | ||
| 15 | #define __KVM_HAVE_DEVICE_ASSIGNMENT | ||
| 16 | #define __KVM_HAVE_MSI | ||
| 17 | #define __KVM_HAVE_USER_NMI | ||
| 18 | #define __KVM_HAVE_GUEST_DEBUG | ||
| 19 | #define __KVM_HAVE_MSIX | ||
| 20 | #define __KVM_HAVE_MCE | ||
| 21 | #define __KVM_HAVE_PIT_STATE2 | ||
| 22 | #define __KVM_HAVE_XEN_HVM | ||
| 23 | #define __KVM_HAVE_VCPU_EVENTS | ||
| 24 | #define __KVM_HAVE_DEBUGREGS | ||
| 25 | #define __KVM_HAVE_XSAVE | ||
| 26 | #define __KVM_HAVE_XCRS | ||
| 27 | |||
| 28 | /* Architectural interrupt line count. */ | ||
| 29 | #define KVM_NR_INTERRUPTS 256 | ||
| 30 | |||
| 31 | struct kvm_memory_alias { | ||
| 32 | __u32 slot; /* this has a different namespace than memory slots */ | ||
| 33 | __u32 flags; | ||
| 34 | __u64 guest_phys_addr; | ||
| 35 | __u64 memory_size; | ||
| 36 | __u64 target_phys_addr; | ||
| 37 | }; | ||
| 38 | |||
| 39 | /* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */ | ||
| 40 | struct kvm_pic_state { | ||
| 41 | __u8 last_irr; /* edge detection */ | ||
| 42 | __u8 irr; /* interrupt request register */ | ||
| 43 | __u8 imr; /* interrupt mask register */ | ||
| 44 | __u8 isr; /* interrupt service register */ | ||
| 45 | __u8 priority_add; /* highest irq priority */ | ||
| 46 | __u8 irq_base; | ||
| 47 | __u8 read_reg_select; | ||
| 48 | __u8 poll; | ||
| 49 | __u8 special_mask; | ||
| 50 | __u8 init_state; | ||
| 51 | __u8 auto_eoi; | ||
| 52 | __u8 rotate_on_auto_eoi; | ||
| 53 | __u8 special_fully_nested_mode; | ||
| 54 | __u8 init4; /* true if 4 byte init */ | ||
| 55 | __u8 elcr; /* PIIX edge/trigger selection */ | ||
| 56 | __u8 elcr_mask; | ||
| 57 | }; | ||
| 58 | |||
| 59 | #define KVM_IOAPIC_NUM_PINS 24 | ||
| 60 | struct kvm_ioapic_state { | ||
| 61 | __u64 base_address; | ||
| 62 | __u32 ioregsel; | ||
| 63 | __u32 id; | ||
| 64 | __u32 irr; | ||
| 65 | __u32 pad; | ||
| 66 | union { | ||
| 67 | __u64 bits; | ||
| 68 | struct { | ||
| 69 | __u8 vector; | ||
| 70 | __u8 delivery_mode:3; | ||
| 71 | __u8 dest_mode:1; | ||
| 72 | __u8 delivery_status:1; | ||
| 73 | __u8 polarity:1; | ||
| 74 | __u8 remote_irr:1; | ||
| 75 | __u8 trig_mode:1; | ||
| 76 | __u8 mask:1; | ||
| 77 | __u8 reserve:7; | ||
| 78 | __u8 reserved[4]; | ||
| 79 | __u8 dest_id; | ||
| 80 | } fields; | ||
| 81 | } redirtbl[KVM_IOAPIC_NUM_PINS]; | ||
| 82 | }; | ||
| 83 | |||
| 84 | #define KVM_IRQCHIP_PIC_MASTER 0 | ||
| 85 | #define KVM_IRQCHIP_PIC_SLAVE 1 | ||
| 86 | #define KVM_IRQCHIP_IOAPIC 2 | ||
| 87 | #define KVM_NR_IRQCHIPS 3 | ||
| 88 | |||
| 89 | /* for KVM_GET_REGS and KVM_SET_REGS */ | ||
| 90 | struct kvm_regs { | ||
| 91 | /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ | ||
| 92 | __u64 rax, rbx, rcx, rdx; | ||
| 93 | __u64 rsi, rdi, rsp, rbp; | ||
| 94 | __u64 r8, r9, r10, r11; | ||
| 95 | __u64 r12, r13, r14, r15; | ||
| 96 | __u64 rip, rflags; | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* for KVM_GET_LAPIC and KVM_SET_LAPIC */ | ||
| 100 | #define KVM_APIC_REG_SIZE 0x400 | ||
| 101 | struct kvm_lapic_state { | ||
| 102 | char regs[KVM_APIC_REG_SIZE]; | ||
| 103 | }; | ||
| 104 | |||
| 105 | struct kvm_segment { | ||
| 106 | __u64 base; | ||
| 107 | __u32 limit; | ||
| 108 | __u16 selector; | ||
| 109 | __u8 type; | ||
| 110 | __u8 present, dpl, db, s, l, g, avl; | ||
| 111 | __u8 unusable; | ||
| 112 | __u8 padding; | ||
| 113 | }; | ||
| 114 | |||
| 115 | struct kvm_dtable { | ||
| 116 | __u64 base; | ||
| 117 | __u16 limit; | ||
| 118 | __u16 padding[3]; | ||
| 119 | }; | ||
| 120 | |||
| 121 | |||
| 122 | /* for KVM_GET_SREGS and KVM_SET_SREGS */ | ||
| 123 | struct kvm_sregs { | ||
| 124 | /* out (KVM_GET_SREGS) / in (KVM_SET_SREGS) */ | ||
| 125 | struct kvm_segment cs, ds, es, fs, gs, ss; | ||
| 126 | struct kvm_segment tr, ldt; | ||
| 127 | struct kvm_dtable gdt, idt; | ||
| 128 | __u64 cr0, cr2, cr3, cr4, cr8; | ||
| 129 | __u64 efer; | ||
| 130 | __u64 apic_base; | ||
| 131 | __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64]; | ||
| 132 | }; | ||
| 133 | |||
| 134 | /* for KVM_GET_FPU and KVM_SET_FPU */ | ||
| 135 | struct kvm_fpu { | ||
| 136 | __u8 fpr[8][16]; | ||
| 137 | __u16 fcw; | ||
| 138 | __u16 fsw; | ||
| 139 | __u8 ftwx; /* in fxsave format */ | ||
| 140 | __u8 pad1; | ||
| 141 | __u16 last_opcode; | ||
| 142 | __u64 last_ip; | ||
| 143 | __u64 last_dp; | ||
| 144 | __u8 xmm[16][16]; | ||
| 145 | __u32 mxcsr; | ||
| 146 | __u32 pad2; | ||
| 147 | }; | ||
| 148 | |||
| 149 | struct kvm_msr_entry { | ||
| 150 | __u32 index; | ||
| 151 | __u32 reserved; | ||
| 152 | __u64 data; | ||
| 153 | }; | ||
| 154 | |||
| 155 | /* for KVM_GET_MSRS and KVM_SET_MSRS */ | ||
| 156 | struct kvm_msrs { | ||
| 157 | __u32 nmsrs; /* number of msrs in entries */ | ||
| 158 | __u32 pad; | ||
| 159 | |||
| 160 | struct kvm_msr_entry entries[0]; | ||
| 161 | }; | ||
| 162 | |||
| 163 | /* for KVM_GET_MSR_INDEX_LIST */ | ||
| 164 | struct kvm_msr_list { | ||
| 165 | __u32 nmsrs; /* number of msrs in entries */ | ||
| 166 | __u32 indices[0]; | ||
| 167 | }; | ||
| 168 | |||
| 169 | |||
| 170 | struct kvm_cpuid_entry { | ||
| 171 | __u32 function; | ||
| 172 | __u32 eax; | ||
| 173 | __u32 ebx; | ||
| 174 | __u32 ecx; | ||
| 175 | __u32 edx; | ||
| 176 | __u32 padding; | ||
| 177 | }; | ||
| 178 | |||
| 179 | /* for KVM_SET_CPUID */ | ||
| 180 | struct kvm_cpuid { | ||
| 181 | __u32 nent; | ||
| 182 | __u32 padding; | ||
| 183 | struct kvm_cpuid_entry entries[0]; | ||
| 184 | }; | ||
| 185 | |||
| 186 | struct kvm_cpuid_entry2 { | ||
| 187 | __u32 function; | ||
| 188 | __u32 index; | ||
| 189 | __u32 flags; | ||
| 190 | __u32 eax; | ||
| 191 | __u32 ebx; | ||
| 192 | __u32 ecx; | ||
| 193 | __u32 edx; | ||
| 194 | __u32 padding[3]; | ||
| 195 | }; | ||
| 196 | |||
| 197 | #define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1 | ||
| 198 | #define KVM_CPUID_FLAG_STATEFUL_FUNC 2 | ||
| 199 | #define KVM_CPUID_FLAG_STATE_READ_NEXT 4 | ||
| 200 | |||
| 201 | /* for KVM_SET_CPUID2 */ | ||
| 202 | struct kvm_cpuid2 { | ||
| 203 | __u32 nent; | ||
| 204 | __u32 padding; | ||
| 205 | struct kvm_cpuid_entry2 entries[0]; | ||
| 206 | }; | ||
| 207 | |||
| 208 | /* for KVM_GET_PIT and KVM_SET_PIT */ | ||
| 209 | struct kvm_pit_channel_state { | ||
| 210 | __u32 count; /* can be 65536 */ | ||
| 211 | __u16 latched_count; | ||
| 212 | __u8 count_latched; | ||
| 213 | __u8 status_latched; | ||
| 214 | __u8 status; | ||
| 215 | __u8 read_state; | ||
| 216 | __u8 write_state; | ||
| 217 | __u8 write_latch; | ||
| 218 | __u8 rw_mode; | ||
| 219 | __u8 mode; | ||
| 220 | __u8 bcd; | ||
| 221 | __u8 gate; | ||
| 222 | __s64 count_load_time; | ||
| 223 | }; | ||
| 224 | |||
| 225 | struct kvm_debug_exit_arch { | ||
| 226 | __u32 exception; | ||
| 227 | __u32 pad; | ||
| 228 | __u64 pc; | ||
| 229 | __u64 dr6; | ||
| 230 | __u64 dr7; | ||
| 231 | }; | ||
| 232 | |||
| 233 | #define KVM_GUESTDBG_USE_SW_BP 0x00010000 | ||
| 234 | #define KVM_GUESTDBG_USE_HW_BP 0x00020000 | ||
| 235 | #define KVM_GUESTDBG_INJECT_DB 0x00040000 | ||
| 236 | #define KVM_GUESTDBG_INJECT_BP 0x00080000 | ||
| 237 | |||
| 238 | /* for KVM_SET_GUEST_DEBUG */ | ||
| 239 | struct kvm_guest_debug_arch { | ||
| 240 | __u64 debugreg[8]; | ||
| 241 | }; | ||
| 242 | |||
| 243 | struct kvm_pit_state { | ||
| 244 | struct kvm_pit_channel_state channels[3]; | ||
| 245 | }; | ||
| 246 | |||
| 247 | #define KVM_PIT_FLAGS_HPET_LEGACY 0x00000001 | ||
| 248 | |||
| 249 | struct kvm_pit_state2 { | ||
| 250 | struct kvm_pit_channel_state channels[3]; | ||
| 251 | __u32 flags; | ||
| 252 | __u32 reserved[9]; | ||
| 253 | }; | ||
| 254 | |||
| 255 | struct kvm_reinject_control { | ||
| 256 | __u8 pit_reinject; | ||
| 257 | __u8 reserved[31]; | ||
| 258 | }; | ||
| 259 | |||
| 260 | /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ | ||
| 261 | #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 | ||
| 262 | #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 | ||
| 263 | #define KVM_VCPUEVENT_VALID_SHADOW 0x00000004 | ||
| 264 | |||
| 265 | /* Interrupt shadow states */ | ||
| 266 | #define KVM_X86_SHADOW_INT_MOV_SS 0x01 | ||
| 267 | #define KVM_X86_SHADOW_INT_STI 0x02 | ||
| 268 | |||
| 269 | /* for KVM_GET/SET_VCPU_EVENTS */ | ||
| 270 | struct kvm_vcpu_events { | ||
| 271 | struct { | ||
| 272 | __u8 injected; | ||
| 273 | __u8 nr; | ||
| 274 | __u8 has_error_code; | ||
| 275 | __u8 pad; | ||
| 276 | __u32 error_code; | ||
| 277 | } exception; | ||
| 278 | struct { | ||
| 279 | __u8 injected; | ||
| 280 | __u8 nr; | ||
| 281 | __u8 soft; | ||
| 282 | __u8 shadow; | ||
| 283 | } interrupt; | ||
| 284 | struct { | ||
| 285 | __u8 injected; | ||
| 286 | __u8 pending; | ||
| 287 | __u8 masked; | ||
| 288 | __u8 pad; | ||
| 289 | } nmi; | ||
| 290 | __u32 sipi_vector; | ||
| 291 | __u32 flags; | ||
| 292 | __u32 reserved[10]; | ||
| 293 | }; | ||
| 294 | |||
| 295 | /* for KVM_GET/SET_DEBUGREGS */ | ||
| 296 | struct kvm_debugregs { | ||
| 297 | __u64 db[4]; | ||
| 298 | __u64 dr6; | ||
| 299 | __u64 dr7; | ||
| 300 | __u64 flags; | ||
| 301 | __u64 reserved[9]; | ||
| 302 | }; | ||
| 303 | |||
| 304 | /* for KVM_CAP_XSAVE */ | ||
| 305 | struct kvm_xsave { | ||
| 306 | __u32 region[1024]; | ||
| 307 | }; | ||
| 308 | |||
| 309 | #define KVM_MAX_XCRS 16 | ||
| 310 | |||
| 311 | struct kvm_xcr { | ||
| 312 | __u32 xcr; | ||
| 313 | __u32 reserved; | ||
| 314 | __u64 value; | ||
| 315 | }; | ||
| 316 | |||
| 317 | struct kvm_xcrs { | ||
| 318 | __u32 nr_xcrs; | ||
| 319 | __u32 flags; | ||
| 320 | struct kvm_xcr xcrs[KVM_MAX_XCRS]; | ||
| 321 | __u64 padding[16]; | ||
| 322 | }; | ||
| 323 | |||
| 324 | #endif /* _ASM_X86_KVM_H */ | ||
diff --git a/arch/x86/include/asm/ldt.h b/arch/x86/include/asm/ldt.h new file mode 100644 index 00000000000..46727eb37bf --- /dev/null +++ b/arch/x86/include/asm/ldt.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * ldt.h | ||
| 3 | * | ||
| 4 | * Definitions of structures used with the modify_ldt system call. | ||
| 5 | */ | ||
| 6 | #ifndef _ASM_X86_LDT_H | ||
| 7 | #define _ASM_X86_LDT_H | ||
| 8 | |||
| 9 | /* Maximum number of LDT entries supported. */ | ||
| 10 | #define LDT_ENTRIES 8192 | ||
| 11 | /* The size of each LDT entry. */ | ||
| 12 | #define LDT_ENTRY_SIZE 8 | ||
| 13 | |||
| 14 | #ifndef __ASSEMBLY__ | ||
| 15 | /* | ||
| 16 | * Note on 64bit base and limit is ignored and you cannot set DS/ES/CS | ||
| 17 | * not to the default values if you still want to do syscalls. This | ||
| 18 | * call is more for 32bit mode therefore. | ||
| 19 | */ | ||
| 20 | struct user_desc { | ||
| 21 | unsigned int entry_number; | ||
| 22 | unsigned int base_addr; | ||
| 23 | unsigned int limit; | ||
| 24 | unsigned int seg_32bit:1; | ||
| 25 | unsigned int contents:2; | ||
| 26 | unsigned int read_exec_only:1; | ||
| 27 | unsigned int limit_in_pages:1; | ||
| 28 | unsigned int seg_not_present:1; | ||
| 29 | unsigned int useable:1; | ||
| 30 | #ifdef __x86_64__ | ||
| 31 | unsigned int lm:1; | ||
| 32 | #endif | ||
| 33 | }; | ||
| 34 | |||
| 35 | #define MODIFY_LDT_CONTENTS_DATA 0 | ||
| 36 | #define MODIFY_LDT_CONTENTS_STACK 1 | ||
| 37 | #define MODIFY_LDT_CONTENTS_CODE 2 | ||
| 38 | |||
| 39 | #endif /* !__ASSEMBLY__ */ | ||
| 40 | #endif /* _ASM_X86_LDT_H */ | ||
diff --git a/arch/x86/include/asm/mca.h b/arch/x86/include/asm/mca.h new file mode 100644 index 00000000000..eedbb6cc1ef --- /dev/null +++ b/arch/x86/include/asm/mca.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* -*- mode: c; c-basic-offset: 8 -*- */ | ||
| 2 | |||
| 3 | /* Platform specific MCA defines */ | ||
| 4 | #ifndef _ASM_X86_MCA_H | ||
| 5 | #define _ASM_X86_MCA_H | ||
| 6 | |||
| 7 | /* Maximal number of MCA slots - actually, some machines have less, but | ||
| 8 | * they all have sufficient number of POS registers to cover 8. | ||
| 9 | */ | ||
| 10 | #define MCA_MAX_SLOT_NR 8 | ||
| 11 | |||
| 12 | /* Most machines have only one MCA bus. The only multiple bus machines | ||
| 13 | * I know have at most two */ | ||
| 14 | #define MAX_MCA_BUSSES 2 | ||
| 15 | |||
| 16 | #define MCA_PRIMARY_BUS 0 | ||
| 17 | #define MCA_SECONDARY_BUS 1 | ||
| 18 | |||
| 19 | /* Dummy slot numbers on primary MCA for integrated functions */ | ||
| 20 | #define MCA_INTEGSCSI (MCA_MAX_SLOT_NR) | ||
| 21 | #define MCA_INTEGVIDEO (MCA_MAX_SLOT_NR+1) | ||
| 22 | #define MCA_MOTHERBOARD (MCA_MAX_SLOT_NR+2) | ||
| 23 | |||
| 24 | /* Dummy POS values for integrated functions */ | ||
| 25 | #define MCA_DUMMY_POS_START 0x10000 | ||
| 26 | #define MCA_INTEGSCSI_POS (MCA_DUMMY_POS_START+1) | ||
| 27 | #define MCA_INTEGVIDEO_POS (MCA_DUMMY_POS_START+2) | ||
| 28 | #define MCA_MOTHERBOARD_POS (MCA_DUMMY_POS_START+3) | ||
| 29 | |||
| 30 | /* MCA registers */ | ||
| 31 | |||
| 32 | #define MCA_MOTHERBOARD_SETUP_REG 0x94 | ||
| 33 | #define MCA_ADAPTER_SETUP_REG 0x96 | ||
| 34 | #define MCA_POS_REG(n) (0x100+(n)) | ||
| 35 | |||
| 36 | #define MCA_ENABLED 0x01 /* POS 2, set if adapter enabled */ | ||
| 37 | |||
| 38 | /* Max number of adapters, including both slots and various integrated | ||
| 39 | * things. | ||
| 40 | */ | ||
| 41 | #define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3) | ||
| 42 | |||
| 43 | #endif /* _ASM_X86_MCA_H */ | ||
diff --git a/arch/x86/include/asm/mca_dma.h b/arch/x86/include/asm/mca_dma.h new file mode 100644 index 00000000000..45271aef82d --- /dev/null +++ b/arch/x86/include/asm/mca_dma.h | |||
| @@ -0,0 +1,201 @@ | |||
| 1 | #ifndef _ASM_X86_MCA_DMA_H | ||
| 2 | #define _ASM_X86_MCA_DMA_H | ||
| 3 | |||
| 4 | #include <asm/io.h> | ||
| 5 | #include <linux/ioport.h> | ||
| 6 | |||
| 7 | /* | ||
| 8 | * Microchannel specific DMA stuff. DMA on an MCA machine is fairly similar to | ||
| 9 | * standard PC dma, but it certainly has its quirks. DMA register addresses | ||
| 10 | * are in a different place and there are some added functions. Most of this | ||
| 11 | * should be pretty obvious on inspection. Note that the user must divide | ||
| 12 | * count by 2 when using 16-bit dma; that is not handled by these functions. | ||
| 13 | * | ||
| 14 | * Ramen Noodles are yummy. | ||
| 15 | * | ||
| 16 | * 1998 Tymm Twillman <tymm@computer.org> | ||
| 17 | */ | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Registers that are used by the DMA controller; FN is the function register | ||
| 21 | * (tell the controller what to do) and EXE is the execution register (how | ||
| 22 | * to do it) | ||
| 23 | */ | ||
| 24 | |||
| 25 | #define MCA_DMA_REG_FN 0x18 | ||
| 26 | #define MCA_DMA_REG_EXE 0x1A | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Functions that the DMA controller can do | ||
| 30 | */ | ||
| 31 | |||
| 32 | #define MCA_DMA_FN_SET_IO 0x00 | ||
| 33 | #define MCA_DMA_FN_SET_ADDR 0x20 | ||
| 34 | #define MCA_DMA_FN_GET_ADDR 0x30 | ||
| 35 | #define MCA_DMA_FN_SET_COUNT 0x40 | ||
| 36 | #define MCA_DMA_FN_GET_COUNT 0x50 | ||
| 37 | #define MCA_DMA_FN_GET_STATUS 0x60 | ||
| 38 | #define MCA_DMA_FN_SET_MODE 0x70 | ||
| 39 | #define MCA_DMA_FN_SET_ARBUS 0x80 | ||
| 40 | #define MCA_DMA_FN_MASK 0x90 | ||
| 41 | #define MCA_DMA_FN_RESET_MASK 0xA0 | ||
| 42 | #define MCA_DMA_FN_MASTER_CLEAR 0xD0 | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Modes (used by setting MCA_DMA_FN_MODE in the function register) | ||
| 46 | * | ||
| 47 | * Note that the MODE_READ is read from memory (write to device), and | ||
| 48 | * MODE_WRITE is vice-versa. | ||
| 49 | */ | ||
| 50 | |||
| 51 | #define MCA_DMA_MODE_XFER 0x04 /* read by default */ | ||
| 52 | #define MCA_DMA_MODE_READ 0x04 /* same as XFER */ | ||
| 53 | #define MCA_DMA_MODE_WRITE 0x08 /* OR with MODE_XFER to use */ | ||
| 54 | #define MCA_DMA_MODE_IO 0x01 /* DMA from IO register */ | ||
| 55 | #define MCA_DMA_MODE_16 0x40 /* 16 bit xfers */ | ||
| 56 | |||
| 57 | |||
| 58 | /** | ||
| 59 | * mca_enable_dma - channel to enable DMA on | ||
| 60 | * @dmanr: DMA channel | ||
| 61 | * | ||
| 62 | * Enable the MCA bus DMA on a channel. This can be called from | ||
| 63 | * IRQ context. | ||
| 64 | */ | ||
| 65 | |||
| 66 | static inline void mca_enable_dma(unsigned int dmanr) | ||
| 67 | { | ||
| 68 | outb(MCA_DMA_FN_RESET_MASK | dmanr, MCA_DMA_REG_FN); | ||
| 69 | } | ||
| 70 | |||
| 71 | /** | ||
| 72 | * mca_disble_dma - channel to disable DMA on | ||
| 73 | * @dmanr: DMA channel | ||
| 74 | * | ||
| 75 | * Enable the MCA bus DMA on a channel. This can be called from | ||
| 76 | * IRQ context. | ||
| 77 | */ | ||
| 78 | |||
| 79 | static inline void mca_disable_dma(unsigned int dmanr) | ||
| 80 | { | ||
| 81 | outb(MCA_DMA_FN_MASK | dmanr, MCA_DMA_REG_FN); | ||
| 82 | } | ||
| 83 | |||
| 84 | /** | ||
| 85 | * mca_set_dma_addr - load a 24bit DMA address | ||
| 86 | * @dmanr: DMA channel | ||
| 87 | * @a: 24bit bus address | ||
| 88 | * | ||
| 89 | * Load the address register in the DMA controller. This has a 24bit | ||
| 90 | * limitation (16Mb). | ||
| 91 | */ | ||
| 92 | |||
| 93 | static inline void mca_set_dma_addr(unsigned int dmanr, unsigned int a) | ||
| 94 | { | ||
| 95 | outb(MCA_DMA_FN_SET_ADDR | dmanr, MCA_DMA_REG_FN); | ||
| 96 | outb(a & 0xff, MCA_DMA_REG_EXE); | ||
| 97 | outb((a >> 8) & 0xff, MCA_DMA_REG_EXE); | ||
| 98 | outb((a >> 16) & 0xff, MCA_DMA_REG_EXE); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * mca_get_dma_addr - load a 24bit DMA address | ||
| 103 | * @dmanr: DMA channel | ||
| 104 | * | ||
| 105 | * Read the address register in the DMA controller. This has a 24bit | ||
| 106 | * limitation (16Mb). The return is a bus address. | ||
| 107 | */ | ||
| 108 | |||
| 109 | static inline unsigned int mca_get_dma_addr(unsigned int dmanr) | ||
| 110 | { | ||
| 111 | unsigned int addr; | ||
| 112 | |||
| 113 | outb(MCA_DMA_FN_GET_ADDR | dmanr, MCA_DMA_REG_FN); | ||
| 114 | addr = inb(MCA_DMA_REG_EXE); | ||
| 115 | addr |= inb(MCA_DMA_REG_EXE) << 8; | ||
| 116 | addr |= inb(MCA_DMA_REG_EXE) << 16; | ||
| 117 | |||
| 118 | return addr; | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * mca_set_dma_count - load a 16bit transfer count | ||
| 123 | * @dmanr: DMA channel | ||
| 124 | * @count: count | ||
| 125 | * | ||
| 126 | * Set the DMA count for this channel. This can be up to 64Kbytes. | ||
| 127 | * Setting a count of zero will not do what you expect. | ||
| 128 | */ | ||
| 129 | |||
| 130 | static inline void mca_set_dma_count(unsigned int dmanr, unsigned int count) | ||
| 131 | { | ||
| 132 | count--; /* transfers one more than count -- correct for this */ | ||
| 133 | |||
| 134 | outb(MCA_DMA_FN_SET_COUNT | dmanr, MCA_DMA_REG_FN); | ||
| 135 | outb(count & 0xff, MCA_DMA_REG_EXE); | ||
| 136 | outb((count >> 8) & 0xff, MCA_DMA_REG_EXE); | ||
| 137 | } | ||
| 138 | |||
| 139 | /** | ||
| 140 | * mca_get_dma_residue - get the remaining bytes to transfer | ||
| 141 | * @dmanr: DMA channel | ||
| 142 | * | ||
| 143 | * This function returns the number of bytes left to transfer | ||
| 144 | * on this DMA channel. | ||
| 145 | */ | ||
| 146 | |||
| 147 | static inline unsigned int mca_get_dma_residue(unsigned int dmanr) | ||
| 148 | { | ||
| 149 | unsigned short count; | ||
| 150 | |||
| 151 | outb(MCA_DMA_FN_GET_COUNT | dmanr, MCA_DMA_REG_FN); | ||
| 152 | count = 1 + inb(MCA_DMA_REG_EXE); | ||
| 153 | count += inb(MCA_DMA_REG_EXE) << 8; | ||
| 154 | |||
| 155 | return count; | ||
| 156 | } | ||
| 157 | |||
| 158 | /** | ||
| 159 | * mca_set_dma_io - set the port for an I/O transfer | ||
| 160 | * @dmanr: DMA channel | ||
| 161 | * @io_addr: an I/O port number | ||
| 162 | * | ||
| 163 | * Unlike the ISA bus DMA controllers the DMA on MCA bus can transfer | ||
| 164 | * with an I/O port target. | ||
| 165 | */ | ||
| 166 | |||
| 167 | static inline void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr) | ||
| 168 | { | ||
| 169 | /* | ||
| 170 | * DMA from a port address -- set the io address | ||
| 171 | */ | ||
| 172 | |||
| 173 | outb(MCA_DMA_FN_SET_IO | dmanr, MCA_DMA_REG_FN); | ||
| 174 | outb(io_addr & 0xff, MCA_DMA_REG_EXE); | ||
| 175 | outb((io_addr >> 8) & 0xff, MCA_DMA_REG_EXE); | ||
| 176 | } | ||
| 177 | |||
| 178 | /** | ||
| 179 | * mca_set_dma_mode - set the DMA mode | ||
| 180 | * @dmanr: DMA channel | ||
| 181 | * @mode: mode to set | ||
| 182 | * | ||
| 183 | * The DMA controller supports several modes. The mode values you can | ||
| 184 | * set are- | ||
| 185 | * | ||
| 186 | * %MCA_DMA_MODE_READ when reading from the DMA device. | ||
| 187 | * | ||
| 188 | * %MCA_DMA_MODE_WRITE to writing to the DMA device. | ||
| 189 | * | ||
| 190 | * %MCA_DMA_MODE_IO to do DMA to or from an I/O port. | ||
| 191 | * | ||
| 192 | * %MCA_DMA_MODE_16 to do 16bit transfers. | ||
| 193 | */ | ||
| 194 | |||
| 195 | static inline void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) | ||
| 196 | { | ||
| 197 | outb(MCA_DMA_FN_SET_MODE | dmanr, MCA_DMA_REG_FN); | ||
| 198 | outb(mode, MCA_DMA_REG_EXE); | ||
| 199 | } | ||
| 200 | |||
| 201 | #endif /* _ASM_X86_MCA_DMA_H */ | ||
diff --git a/arch/x86/include/asm/memblock.h b/arch/x86/include/asm/memblock.h new file mode 100644 index 00000000000..0cd3800f33b --- /dev/null +++ b/arch/x86/include/asm/memblock.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #ifndef _X86_MEMBLOCK_H | ||
| 2 | #define _X86_MEMBLOCK_H | ||
| 3 | |||
| 4 | #define ARCH_DISCARD_MEMBLOCK | ||
| 5 | |||
| 6 | u64 memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align); | ||
| 7 | |||
| 8 | void memblock_x86_reserve_range(u64 start, u64 end, char *name); | ||
| 9 | void memblock_x86_free_range(u64 start, u64 end); | ||
| 10 | struct range; | ||
| 11 | int __get_free_all_memory_range(struct range **range, int nodeid, | ||
| 12 | unsigned long start_pfn, unsigned long end_pfn); | ||
| 13 | int get_free_all_memory_range(struct range **rangep, int nodeid); | ||
| 14 | |||
| 15 | void memblock_x86_register_active_regions(int nid, unsigned long start_pfn, | ||
| 16 | unsigned long last_pfn); | ||
| 17 | u64 memblock_x86_hole_size(u64 start, u64 end); | ||
| 18 | u64 memblock_x86_find_in_range_node(int nid, u64 start, u64 end, u64 size, u64 align); | ||
| 19 | u64 memblock_x86_free_memory_in_range(u64 addr, u64 limit); | ||
| 20 | u64 memblock_x86_memory_in_range(u64 addr, u64 limit); | ||
| 21 | bool memblock_x86_check_reserved_size(u64 *addrp, u64 *sizep, u64 align); | ||
| 22 | |||
| 23 | #endif | ||
diff --git a/arch/x86/include/asm/mman.h b/arch/x86/include/asm/mman.h new file mode 100644 index 00000000000..593e51d4643 --- /dev/null +++ b/arch/x86/include/asm/mman.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #ifndef _ASM_X86_MMAN_H | ||
| 2 | #define _ASM_X86_MMAN_H | ||
| 3 | |||
| 4 | #define MAP_32BIT 0x40 /* only give out 32bit addresses */ | ||
| 5 | |||
| 6 | #include <asm-generic/mman.h> | ||
| 7 | |||
| 8 | #endif /* _ASM_X86_MMAN_H */ | ||
diff --git a/arch/x86/include/asm/msgbuf.h b/arch/x86/include/asm/msgbuf.h new file mode 100644 index 00000000000..809134c644a --- /dev/null +++ b/arch/x86/include/asm/msgbuf.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/msgbuf.h> | |||
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h new file mode 100644 index 00000000000..d52609aeeab --- /dev/null +++ b/arch/x86/include/asm/msr-index.h | |||
| @@ -0,0 +1,463 @@ | |||
| 1 | #ifndef _ASM_X86_MSR_INDEX_H | ||
| 2 | #define _ASM_X86_MSR_INDEX_H | ||
| 3 | |||
| 4 | /* CPU model specific register (MSR) numbers */ | ||
| 5 | |||
| 6 | /* x86-64 specific MSRs */ | ||
| 7 | #define MSR_EFER 0xc0000080 /* extended feature register */ | ||
| 8 | #define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */ | ||
| 9 | #define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ | ||
| 10 | #define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target */ | ||
| 11 | #define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ | ||
| 12 | #define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ | ||
| 13 | #define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ | ||
| 14 | #define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */ | ||
| 15 | #define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */ | ||
| 16 | |||
| 17 | /* EFER bits: */ | ||
| 18 | #define _EFER_SCE 0 /* SYSCALL/SYSRET */ | ||
| 19 | #define _EFER_LME 8 /* Long mode enable */ | ||
| 20 | #define _EFER_LMA 10 /* Long mode active (read-only) */ | ||
| 21 | #define _EFER_NX 11 /* No execute enable */ | ||
| 22 | #define _EFER_SVME 12 /* Enable virtualization */ | ||
| 23 | #define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */ | ||
| 24 | #define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */ | ||
| 25 | |||
| 26 | #define EFER_SCE (1<<_EFER_SCE) | ||
| 27 | #define EFER_LME (1<<_EFER_LME) | ||
| 28 | #define EFER_LMA (1<<_EFER_LMA) | ||
| 29 | #define EFER_NX (1<<_EFER_NX) | ||
| 30 | #define EFER_SVME (1<<_EFER_SVME) | ||
| 31 | #define EFER_LMSLE (1<<_EFER_LMSLE) | ||
| 32 | #define EFER_FFXSR (1<<_EFER_FFXSR) | ||
| 33 | |||
| 34 | /* Intel MSRs. Some also available on other CPUs */ | ||
| 35 | #define MSR_IA32_PERFCTR0 0x000000c1 | ||
| 36 | #define MSR_IA32_PERFCTR1 0x000000c2 | ||
| 37 | #define MSR_FSB_FREQ 0x000000cd | ||
| 38 | |||
| 39 | #define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 | ||
| 40 | #define NHM_C3_AUTO_DEMOTE (1UL << 25) | ||
| 41 | #define NHM_C1_AUTO_DEMOTE (1UL << 26) | ||
| 42 | #define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25) | ||
| 43 | |||
| 44 | #define MSR_MTRRcap 0x000000fe | ||
| 45 | #define MSR_IA32_BBL_CR_CTL 0x00000119 | ||
| 46 | #define MSR_IA32_BBL_CR_CTL3 0x0000011e | ||
| 47 | |||
| 48 | #define MSR_IA32_SYSENTER_CS 0x00000174 | ||
| 49 | #define MSR_IA32_SYSENTER_ESP 0x00000175 | ||
| 50 | #define MSR_IA32_SYSENTER_EIP 0x00000176 | ||
| 51 | |||
| 52 | #define MSR_IA32_MCG_CAP 0x00000179 | ||
| 53 | #define MSR_IA32_MCG_STATUS 0x0000017a | ||
| 54 | #define MSR_IA32_MCG_CTL 0x0000017b | ||
| 55 | |||
| 56 | #define MSR_OFFCORE_RSP_0 0x000001a6 | ||
| 57 | #define MSR_OFFCORE_RSP_1 0x000001a7 | ||
| 58 | |||
| 59 | #define MSR_IA32_PEBS_ENABLE 0x000003f1 | ||
| 60 | #define MSR_IA32_DS_AREA 0x00000600 | ||
| 61 | #define MSR_IA32_PERF_CAPABILITIES 0x00000345 | ||
| 62 | |||
| 63 | #define MSR_MTRRfix64K_00000 0x00000250 | ||
| 64 | #define MSR_MTRRfix16K_80000 0x00000258 | ||
| 65 | #define MSR_MTRRfix16K_A0000 0x00000259 | ||
| 66 | #define MSR_MTRRfix4K_C0000 0x00000268 | ||
| 67 | #define MSR_MTRRfix4K_C8000 0x00000269 | ||
| 68 | #define MSR_MTRRfix4K_D0000 0x0000026a | ||
| 69 | #define MSR_MTRRfix4K_D8000 0x0000026b | ||
| 70 | #define MSR_MTRRfix4K_E0000 0x0000026c | ||
| 71 | #define MSR_MTRRfix4K_E8000 0x0000026d | ||
| 72 | #define MSR_MTRRfix4K_F0000 0x0000026e | ||
| 73 | #define MSR_MTRRfix4K_F8000 0x0000026f | ||
| 74 | #define MSR_MTRRdefType 0x000002ff | ||
| 75 | |||
| 76 | #define MSR_IA32_CR_PAT 0x00000277 | ||
| 77 | |||
| 78 | #define MSR_IA32_DEBUGCTLMSR 0x000001d9 | ||
| 79 | #define MSR_IA32_LASTBRANCHFROMIP 0x000001db | ||
| 80 | #define MSR_IA32_LASTBRANCHTOIP 0x000001dc | ||
| 81 | #define MSR_IA32_LASTINTFROMIP 0x000001dd | ||
| 82 | #define MSR_IA32_LASTINTTOIP 0x000001de | ||
| 83 | |||
| 84 | /* DEBUGCTLMSR bits (others vary by model): */ | ||
| 85 | #define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ | ||
| 86 | #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ | ||
| 87 | #define DEBUGCTLMSR_TR (1UL << 6) | ||
| 88 | #define DEBUGCTLMSR_BTS (1UL << 7) | ||
| 89 | #define DEBUGCTLMSR_BTINT (1UL << 8) | ||
| 90 | #define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9) | ||
| 91 | #define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10) | ||
| 92 | #define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11) | ||
| 93 | |||
| 94 | #define MSR_IA32_MC0_CTL 0x00000400 | ||
| 95 | #define MSR_IA32_MC0_STATUS 0x00000401 | ||
| 96 | #define MSR_IA32_MC0_ADDR 0x00000402 | ||
| 97 | #define MSR_IA32_MC0_MISC 0x00000403 | ||
| 98 | |||
| 99 | #define MSR_AMD64_MC0_MASK 0xc0010044 | ||
| 100 | |||
| 101 | #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) | ||
| 102 | #define MSR_IA32_MCx_STATUS(x) (MSR_IA32_MC0_STATUS + 4*(x)) | ||
| 103 | #define MSR_IA32_MCx_ADDR(x) (MSR_IA32_MC0_ADDR + 4*(x)) | ||
| 104 | #define MSR_IA32_MCx_MISC(x) (MSR_IA32_MC0_MISC + 4*(x)) | ||
| 105 | |||
| 106 | #define MSR_AMD64_MCx_MASK(x) (MSR_AMD64_MC0_MASK + (x)) | ||
| 107 | |||
| 108 | /* These are consecutive and not in the normal 4er MCE bank block */ | ||
| 109 | #define MSR_IA32_MC0_CTL2 0x00000280 | ||
| 110 | #define MSR_IA32_MCx_CTL2(x) (MSR_IA32_MC0_CTL2 + (x)) | ||
| 111 | |||
| 112 | #define MSR_P6_PERFCTR0 0x000000c1 | ||
| 113 | #define MSR_P6_PERFCTR1 0x000000c2 | ||
| 114 | #define MSR_P6_EVNTSEL0 0x00000186 | ||
| 115 | #define MSR_P6_EVNTSEL1 0x00000187 | ||
| 116 | |||
| 117 | /* AMD64 MSRs. Not complete. See the architecture manual for a more | ||
| 118 | complete list. */ | ||
| 119 | |||
| 120 | #define MSR_AMD64_PATCH_LEVEL 0x0000008b | ||
| 121 | #define MSR_AMD64_TSC_RATIO 0xc0000104 | ||
| 122 | #define MSR_AMD64_NB_CFG 0xc001001f | ||
| 123 | #define MSR_AMD64_PATCH_LOADER 0xc0010020 | ||
| 124 | #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 | ||
| 125 | #define MSR_AMD64_OSVW_STATUS 0xc0010141 | ||
| 126 | #define MSR_AMD64_DC_CFG 0xc0011022 | ||
| 127 | #define MSR_AMD64_IBSFETCHCTL 0xc0011030 | ||
| 128 | #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 | ||
| 129 | #define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 | ||
| 130 | #define MSR_AMD64_IBSOPCTL 0xc0011033 | ||
| 131 | #define MSR_AMD64_IBSOPRIP 0xc0011034 | ||
| 132 | #define MSR_AMD64_IBSOPDATA 0xc0011035 | ||
| 133 | #define MSR_AMD64_IBSOPDATA2 0xc0011036 | ||
| 134 | #define MSR_AMD64_IBSOPDATA3 0xc0011037 | ||
| 135 | #define MSR_AMD64_IBSDCLINAD 0xc0011038 | ||
| 136 | #define MSR_AMD64_IBSDCPHYSAD 0xc0011039 | ||
| 137 | #define MSR_AMD64_IBSCTL 0xc001103a | ||
| 138 | #define MSR_AMD64_IBSBRTARGET 0xc001103b | ||
| 139 | |||
| 140 | /* Fam 15h MSRs */ | ||
| 141 | #define MSR_F15H_PERF_CTL 0xc0010200 | ||
| 142 | #define MSR_F15H_PERF_CTR 0xc0010201 | ||
| 143 | |||
| 144 | /* Fam 10h MSRs */ | ||
| 145 | #define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 | ||
| 146 | #define FAM10H_MMIO_CONF_ENABLE (1<<0) | ||
| 147 | #define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf | ||
| 148 | #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 | ||
| 149 | #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL | ||
| 150 | #define FAM10H_MMIO_CONF_BASE_SHIFT 20 | ||
| 151 | #define MSR_FAM10H_NODE_ID 0xc001100c | ||
| 152 | |||
| 153 | /* K8 MSRs */ | ||
| 154 | #define MSR_K8_TOP_MEM1 0xc001001a | ||
| 155 | #define MSR_K8_TOP_MEM2 0xc001001d | ||
| 156 | #define MSR_K8_SYSCFG 0xc0010010 | ||
| 157 | #define MSR_K8_INT_PENDING_MSG 0xc0010055 | ||
| 158 | /* C1E active bits in int pending message */ | ||
| 159 | #define K8_INTP_C1E_ACTIVE_MASK 0x18000000 | ||
| 160 | #define MSR_K8_TSEG_ADDR 0xc0010112 | ||
| 161 | #define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */ | ||
| 162 | #define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */ | ||
| 163 | #define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */ | ||
| 164 | |||
| 165 | /* K7 MSRs */ | ||
| 166 | #define MSR_K7_EVNTSEL0 0xc0010000 | ||
| 167 | #define MSR_K7_PERFCTR0 0xc0010004 | ||
| 168 | #define MSR_K7_EVNTSEL1 0xc0010001 | ||
| 169 | #define MSR_K7_PERFCTR1 0xc0010005 | ||
| 170 | #define MSR_K7_EVNTSEL2 0xc0010002 | ||
| 171 | #define MSR_K7_PERFCTR2 0xc0010006 | ||
| 172 | #define MSR_K7_EVNTSEL3 0xc0010003 | ||
| 173 | #define MSR_K7_PERFCTR3 0xc0010007 | ||
| 174 | #define MSR_K7_CLK_CTL 0xc001001b | ||
| 175 | #define MSR_K7_HWCR 0xc0010015 | ||
| 176 | #define MSR_K7_FID_VID_CTL 0xc0010041 | ||
| 177 | #define MSR_K7_FID_VID_STATUS 0xc0010042 | ||
| 178 | |||
| 179 | /* K6 MSRs */ | ||
| 180 | #define MSR_K6_WHCR 0xc0000082 | ||
| 181 | #define MSR_K6_UWCCR 0xc0000085 | ||
| 182 | #define MSR_K6_EPMR 0xc0000086 | ||
| 183 | #define MSR_K6_PSOR 0xc0000087 | ||
| 184 | #define MSR_K6_PFIR 0xc0000088 | ||
| 185 | |||
| 186 | /* Centaur-Hauls/IDT defined MSRs. */ | ||
| 187 | #define MSR_IDT_FCR1 0x00000107 | ||
| 188 | #define MSR_IDT_FCR2 0x00000108 | ||
| 189 | #define MSR_IDT_FCR3 0x00000109 | ||
| 190 | #define MSR_IDT_FCR4 0x0000010a | ||
| 191 | |||
| 192 | #define MSR_IDT_MCR0 0x00000110 | ||
| 193 | #define MSR_IDT_MCR1 0x00000111 | ||
| 194 | #define MSR_IDT_MCR2 0x00000112 | ||
| 195 | #define MSR_IDT_MCR3 0x00000113 | ||
| 196 | #define MSR_IDT_MCR4 0x00000114 | ||
| 197 | #define MSR_IDT_MCR5 0x00000115 | ||
| 198 | #define MSR_IDT_MCR6 0x00000116 | ||
| 199 | #define MSR_IDT_MCR7 0x00000117 | ||
| 200 | #define MSR_IDT_MCR_CTRL 0x00000120 | ||
| 201 | |||
| 202 | /* VIA Cyrix defined MSRs*/ | ||
| 203 | #define MSR_VIA_FCR 0x00001107 | ||
| 204 | #define MSR_VIA_LONGHAUL 0x0000110a | ||
| 205 | #define MSR_VIA_RNG 0x0000110b | ||
| 206 | #define MSR_VIA_BCR2 0x00001147 | ||
| 207 | |||
| 208 | /* Transmeta defined MSRs */ | ||
| 209 | #define MSR_TMTA_LONGRUN_CTRL 0x80868010 | ||
| 210 | #define MSR_TMTA_LONGRUN_FLAGS 0x80868011 | ||
| 211 | #define MSR_TMTA_LRTI_READOUT 0x80868018 | ||
| 212 | #define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a | ||
| 213 | |||
| 214 | /* Intel defined MSRs. */ | ||
| 215 | #define MSR_IA32_P5_MC_ADDR 0x00000000 | ||
| 216 | #define MSR_IA32_P5_MC_TYPE 0x00000001 | ||
| 217 | #define MSR_IA32_TSC 0x00000010 | ||
| 218 | #define MSR_IA32_PLATFORM_ID 0x00000017 | ||
| 219 | #define MSR_IA32_EBL_CR_POWERON 0x0000002a | ||
| 220 | #define MSR_EBC_FREQUENCY_ID 0x0000002c | ||
| 221 | #define MSR_IA32_FEATURE_CONTROL 0x0000003a | ||
| 222 | |||
| 223 | #define FEATURE_CONTROL_LOCKED (1<<0) | ||
| 224 | #define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) | ||
| 225 | #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) | ||
| 226 | |||
| 227 | #define MSR_IA32_APICBASE 0x0000001b | ||
| 228 | #define MSR_IA32_APICBASE_BSP (1<<8) | ||
| 229 | #define MSR_IA32_APICBASE_ENABLE (1<<11) | ||
| 230 | #define MSR_IA32_APICBASE_BASE (0xfffff<<12) | ||
| 231 | |||
| 232 | #define MSR_IA32_UCODE_WRITE 0x00000079 | ||
| 233 | #define MSR_IA32_UCODE_REV 0x0000008b | ||
| 234 | |||
| 235 | #define MSR_IA32_PERF_STATUS 0x00000198 | ||
| 236 | #define MSR_IA32_PERF_CTL 0x00000199 | ||
| 237 | |||
| 238 | #define MSR_IA32_MPERF 0x000000e7 | ||
| 239 | #define MSR_IA32_APERF 0x000000e8 | ||
| 240 | |||
| 241 | #define MSR_IA32_THERM_CONTROL 0x0000019a | ||
| 242 | #define MSR_IA32_THERM_INTERRUPT 0x0000019b | ||
| 243 | |||
| 244 | #define THERM_INT_HIGH_ENABLE (1 << 0) | ||
| 245 | #define THERM_INT_LOW_ENABLE (1 << 1) | ||
| 246 | #define THERM_INT_PLN_ENABLE (1 << 24) | ||
| 247 | |||
| 248 | #define MSR_IA32_THERM_STATUS 0x0000019c | ||
| 249 | |||
| 250 | #define THERM_STATUS_PROCHOT (1 << 0) | ||
| 251 | #define THERM_STATUS_POWER_LIMIT (1 << 10) | ||
| 252 | |||
| 253 | #define MSR_THERM2_CTL 0x0000019d | ||
| 254 | |||
| 255 | #define MSR_THERM2_CTL_TM_SELECT (1ULL << 16) | ||
| 256 | |||
| 257 | #define MSR_IA32_MISC_ENABLE 0x000001a0 | ||
| 258 | |||
| 259 | #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 | ||
| 260 | |||
| 261 | #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 | ||
| 262 | #define ENERGY_PERF_BIAS_PERFORMANCE 0 | ||
| 263 | #define ENERGY_PERF_BIAS_NORMAL 6 | ||
| 264 | #define ENERGY_PERF_BIAS_POWERSAVE 15 | ||
| 265 | |||
| 266 | #define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1 | ||
| 267 | |||
| 268 | #define PACKAGE_THERM_STATUS_PROCHOT (1 << 0) | ||
| 269 | #define PACKAGE_THERM_STATUS_POWER_LIMIT (1 << 10) | ||
| 270 | |||
| 271 | #define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2 | ||
| 272 | |||
| 273 | #define PACKAGE_THERM_INT_HIGH_ENABLE (1 << 0) | ||
| 274 | #define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1) | ||
| 275 | #define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24) | ||
| 276 | |||
| 277 | /* Thermal Thresholds Support */ | ||
| 278 | #define THERM_INT_THRESHOLD0_ENABLE (1 << 15) | ||
| 279 | #define THERM_SHIFT_THRESHOLD0 8 | ||
| 280 | #define THERM_MASK_THRESHOLD0 (0x7f << THERM_SHIFT_THRESHOLD0) | ||
| 281 | #define THERM_INT_THRESHOLD1_ENABLE (1 << 23) | ||
| 282 | #define THERM_SHIFT_THRESHOLD1 16 | ||
| 283 | #define THERM_MASK_THRESHOLD1 (0x7f << THERM_SHIFT_THRESHOLD1) | ||
| 284 | #define THERM_STATUS_THRESHOLD0 (1 << 6) | ||
| 285 | #define THERM_LOG_THRESHOLD0 (1 << 7) | ||
| 286 | #define THERM_STATUS_THRESHOLD1 (1 << 8) | ||
| 287 | #define THERM_LOG_THRESHOLD1 (1 << 9) | ||
| 288 | |||
| 289 | /* MISC_ENABLE bits: architectural */ | ||
| 290 | #define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) | ||
| 291 | #define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) | ||
| 292 | #define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) | ||
| 293 | #define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) | ||
| 294 | #define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) | ||
| 295 | #define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) | ||
| 296 | #define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) | ||
| 297 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22) | ||
| 298 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) | ||
| 299 | #define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) | ||
| 300 | |||
| 301 | /* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ | ||
| 302 | #define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2) | ||
| 303 | #define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3) | ||
| 304 | #define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) | ||
| 305 | #define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) | ||
| 306 | #define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) | ||
| 307 | #define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9) | ||
| 308 | #define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) | ||
| 309 | #define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) | ||
| 310 | #define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) | ||
| 311 | #define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19) | ||
| 312 | #define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20) | ||
| 313 | #define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24) | ||
| 314 | #define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37) | ||
| 315 | #define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) | ||
| 316 | #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) | ||
| 317 | |||
| 318 | /* P4/Xeon+ specific */ | ||
| 319 | #define MSR_IA32_MCG_EAX 0x00000180 | ||
| 320 | #define MSR_IA32_MCG_EBX 0x00000181 | ||
| 321 | #define MSR_IA32_MCG_ECX 0x00000182 | ||
| 322 | #define MSR_IA32_MCG_EDX 0x00000183 | ||
| 323 | #define MSR_IA32_MCG_ESI 0x00000184 | ||
| 324 | #define MSR_IA32_MCG_EDI 0x00000185 | ||
| 325 | #define MSR_IA32_MCG_EBP 0x00000186 | ||
| 326 | #define MSR_IA32_MCG_ESP 0x00000187 | ||
| 327 | #define MSR_IA32_MCG_EFLAGS 0x00000188 | ||
| 328 | #define MSR_IA32_MCG_EIP 0x00000189 | ||
| 329 | #define MSR_IA32_MCG_RESERVED 0x0000018a | ||
| 330 | |||
| 331 | /* Pentium IV performance counter MSRs */ | ||
| 332 | #define MSR_P4_BPU_PERFCTR0 0x00000300 | ||
| 333 | #define MSR_P4_BPU_PERFCTR1 0x00000301 | ||
| 334 | #define MSR_P4_BPU_PERFCTR2 0x00000302 | ||
| 335 | #define MSR_P4_BPU_PERFCTR3 0x00000303 | ||
| 336 | #define MSR_P4_MS_PERFCTR0 0x00000304 | ||
| 337 | #define MSR_P4_MS_PERFCTR1 0x00000305 | ||
| 338 | #define MSR_P4_MS_PERFCTR2 0x00000306 | ||
| 339 | #define MSR_P4_MS_PERFCTR3 0x00000307 | ||
| 340 | #define MSR_P4_FLAME_PERFCTR0 0x00000308 | ||
| 341 | #define MSR_P4_FLAME_PERFCTR1 0x00000309 | ||
| 342 | #define MSR_P4_FLAME_PERFCTR2 0x0000030a | ||
| 343 | #define MSR_P4_FLAME_PERFCTR3 0x0000030b | ||
| 344 | #define MSR_P4_IQ_PERFCTR0 0x0000030c | ||
| 345 | #define MSR_P4_IQ_PERFCTR1 0x0000030d | ||
| 346 | #define MSR_P4_IQ_PERFCTR2 0x0000030e | ||
| 347 | #define MSR_P4_IQ_PERFCTR3 0x0000030f | ||
| 348 | #define MSR_P4_IQ_PERFCTR4 0x00000310 | ||
| 349 | #define MSR_P4_IQ_PERFCTR5 0x00000311 | ||
| 350 | #define MSR_P4_BPU_CCCR0 0x00000360 | ||
| 351 | #define MSR_P4_BPU_CCCR1 0x00000361 | ||
| 352 | #define MSR_P4_BPU_CCCR2 0x00000362 | ||
| 353 | #define MSR_P4_BPU_CCCR3 0x00000363 | ||
| 354 | #define MSR_P4_MS_CCCR0 0x00000364 | ||
| 355 | #define MSR_P4_MS_CCCR1 0x00000365 | ||
| 356 | #define MSR_P4_MS_CCCR2 0x00000366 | ||
| 357 | #define MSR_P4_MS_CCCR3 0x00000367 | ||
| 358 | #define MSR_P4_FLAME_CCCR0 0x00000368 | ||
| 359 | #define MSR_P4_FLAME_CCCR1 0x00000369 | ||
| 360 | #define MSR_P4_FLAME_CCCR2 0x0000036a | ||
| 361 | #define MSR_P4_FLAME_CCCR3 0x0000036b | ||
| 362 | #define MSR_P4_IQ_CCCR0 0x0000036c | ||
| 363 | #define MSR_P4_IQ_CCCR1 0x0000036d | ||
| 364 | #define MSR_P4_IQ_CCCR2 0x0000036e | ||
| 365 | #define MSR_P4_IQ_CCCR3 0x0000036f | ||
| 366 | #define MSR_P4_IQ_CCCR4 0x00000370 | ||
| 367 | #define MSR_P4_IQ_CCCR5 0x00000371 | ||
| 368 | #define MSR_P4_ALF_ESCR0 0x000003ca | ||
| 369 | #define MSR_P4_ALF_ESCR1 0x000003cb | ||
| 370 | #define MSR_P4_BPU_ESCR0 0x000003b2 | ||
| 371 | #define MSR_P4_BPU_ESCR1 0x000003b3 | ||
| 372 | #define MSR_P4_BSU_ESCR0 0x000003a0 | ||
| 373 | #define MSR_P4_BSU_ESCR1 0x000003a1 | ||
| 374 | #define MSR_P4_CRU_ESCR0 0x000003b8 | ||
| 375 | #define MSR_P4_CRU_ESCR1 0x000003b9 | ||
| 376 | #define MSR_P4_CRU_ESCR2 0x000003cc | ||
| 377 | #define MSR_P4_CRU_ESCR3 0x000003cd | ||
| 378 | #define MSR_P4_CRU_ESCR4 0x000003e0 | ||
| 379 | #define MSR_P4_CRU_ESCR5 0x000003e1 | ||
| 380 | #define MSR_P4_DAC_ESCR0 0x000003a8 | ||
| 381 | #define MSR_P4_DAC_ESCR1 0x000003a9 | ||
| 382 | #define MSR_P4_FIRM_ESCR0 0x000003a4 | ||
| 383 | #define MSR_P4_FIRM_ESCR1 0x000003a5 | ||
| 384 | #define MSR_P4_FLAME_ESCR0 0x000003a6 | ||
| 385 | #define MSR_P4_FLAME_ESCR1 0x000003a7 | ||
| 386 | #define MSR_P4_FSB_ESCR0 0x000003a2 | ||
| 387 | #define MSR_P4_FSB_ESCR1 0x000003a3 | ||
| 388 | #define MSR_P4_IQ_ESCR0 0x000003ba | ||
| 389 | #define MSR_P4_IQ_ESCR1 0x000003bb | ||
| 390 | #define MSR_P4_IS_ESCR0 0x000003b4 | ||
| 391 | #define MSR_P4_IS_ESCR1 0x000003b5 | ||
| 392 | #define MSR_P4_ITLB_ESCR0 0x000003b6 | ||
| 393 | #define MSR_P4_ITLB_ESCR1 0x000003b7 | ||
| 394 | #define MSR_P4_IX_ESCR0 0x000003c8 | ||
| 395 | #define MSR_P4_IX_ESCR1 0x000003c9 | ||
| 396 | #define MSR_P4_MOB_ESCR0 0x000003aa | ||
| 397 | #define MSR_P4_MOB_ESCR1 0x000003ab | ||
| 398 | #define MSR_P4_MS_ESCR0 0x000003c0 | ||
| 399 | #define MSR_P4_MS_ESCR1 0x000003c1 | ||
| 400 | #define MSR_P4_PMH_ESCR0 0x000003ac | ||
| 401 | #define MSR_P4_PMH_ESCR1 0x000003ad | ||
| 402 | #define MSR_P4_RAT_ESCR0 0x000003bc | ||
| 403 | #define MSR_P4_RAT_ESCR1 0x000003bd | ||
| 404 | #define MSR_P4_SAAT_ESCR0 0x000003ae | ||
| 405 | #define MSR_P4_SAAT_ESCR1 0x000003af | ||
| 406 | #define MSR_P4_SSU_ESCR0 0x000003be | ||
| 407 | #define MSR_P4_SSU_ESCR1 0x000003bf /* guess: not in manual */ | ||
| 408 | |||
| 409 | #define MSR_P4_TBPU_ESCR0 0x000003c2 | ||
| 410 | #define MSR_P4_TBPU_ESCR1 0x000003c3 | ||
| 411 | #define MSR_P4_TC_ESCR0 0x000003c4 | ||
| 412 | #define MSR_P4_TC_ESCR1 0x000003c5 | ||
| 413 | #define MSR_P4_U2L_ESCR0 0x000003b0 | ||
| 414 | #define MSR_P4_U2L_ESCR1 0x000003b1 | ||
| 415 | |||
| 416 | #define MSR_P4_PEBS_MATRIX_VERT 0x000003f2 | ||
| 417 | |||
| 418 | /* Intel Core-based CPU performance counters */ | ||
| 419 | #define MSR_CORE_PERF_FIXED_CTR0 0x00000309 | ||
| 420 | #define MSR_CORE_PERF_FIXED_CTR1 0x0000030a | ||
| 421 | #define MSR_CORE_PERF_FIXED_CTR2 0x0000030b | ||
| 422 | #define MSR_CORE_PERF_FIXED_CTR_CTRL 0x0000038d | ||
| 423 | #define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e | ||
| 424 | #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f | ||
| 425 | #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 | ||
| 426 | |||
| 427 | /* Geode defined MSRs */ | ||
| 428 | #define MSR_GEODE_BUSCONT_CONF0 0x00001900 | ||
| 429 | |||
| 430 | /* Intel VT MSRs */ | ||
| 431 | #define MSR_IA32_VMX_BASIC 0x00000480 | ||
| 432 | #define MSR_IA32_VMX_PINBASED_CTLS 0x00000481 | ||
| 433 | #define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482 | ||
| 434 | #define MSR_IA32_VMX_EXIT_CTLS 0x00000483 | ||
| 435 | #define MSR_IA32_VMX_ENTRY_CTLS 0x00000484 | ||
| 436 | #define MSR_IA32_VMX_MISC 0x00000485 | ||
| 437 | #define MSR_IA32_VMX_CR0_FIXED0 0x00000486 | ||
| 438 | #define MSR_IA32_VMX_CR0_FIXED1 0x00000487 | ||
| 439 | #define MSR_IA32_VMX_CR4_FIXED0 0x00000488 | ||
| 440 | #define MSR_IA32_VMX_CR4_FIXED1 0x00000489 | ||
| 441 | #define MSR_IA32_VMX_VMCS_ENUM 0x0000048a | ||
| 442 | #define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b | ||
| 443 | #define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c | ||
| 444 | #define MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x0000048d | ||
| 445 | #define MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x0000048e | ||
| 446 | #define MSR_IA32_VMX_TRUE_EXIT_CTLS 0x0000048f | ||
| 447 | #define MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x00000490 | ||
| 448 | |||
| 449 | /* VMX_BASIC bits and bitmasks */ | ||
| 450 | #define VMX_BASIC_VMCS_SIZE_SHIFT 32 | ||
| 451 | #define VMX_BASIC_64 0x0001000000000000LLU | ||
| 452 | #define VMX_BASIC_MEM_TYPE_SHIFT 50 | ||
| 453 | #define VMX_BASIC_MEM_TYPE_MASK 0x003c000000000000LLU | ||
| 454 | #define VMX_BASIC_MEM_TYPE_WB 6LLU | ||
| 455 | #define VMX_BASIC_INOUT 0x0040000000000000LLU | ||
| 456 | |||
| 457 | /* AMD-V MSRs */ | ||
| 458 | |||
| 459 | #define MSR_VM_CR 0xc0010114 | ||
| 460 | #define MSR_VM_IGNNE 0xc0010115 | ||
| 461 | #define MSR_VM_HSAVE_PA 0xc0010117 | ||
| 462 | |||
| 463 | #endif /* _ASM_X86_MSR_INDEX_H */ | ||
diff --git a/arch/x86/include/asm/param.h b/arch/x86/include/asm/param.h new file mode 100644 index 00000000000..965d4542797 --- /dev/null +++ b/arch/x86/include/asm/param.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/param.h> | |||
diff --git a/arch/x86/include/asm/poll.h b/arch/x86/include/asm/poll.h new file mode 100644 index 00000000000..c98509d3149 --- /dev/null +++ b/arch/x86/include/asm/poll.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/poll.h> | |||
diff --git a/arch/x86/include/asm/posix_types_32.h b/arch/x86/include/asm/posix_types_32.h new file mode 100644 index 00000000000..f7d9adf82e5 --- /dev/null +++ b/arch/x86/include/asm/posix_types_32.h | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | #ifndef _ASM_X86_POSIX_TYPES_32_H | ||
| 2 | #define _ASM_X86_POSIX_TYPES_32_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * This file is generally used by user-level software, so you need to | ||
| 6 | * be a little careful about namespace pollution etc. Also, we cannot | ||
| 7 | * assume GCC is being used. | ||
| 8 | */ | ||
| 9 | |||
| 10 | typedef unsigned long __kernel_ino_t; | ||
| 11 | typedef unsigned short __kernel_mode_t; | ||
| 12 | typedef unsigned short __kernel_nlink_t; | ||
| 13 | typedef long __kernel_off_t; | ||
| 14 | typedef int __kernel_pid_t; | ||
| 15 | typedef unsigned short __kernel_ipc_pid_t; | ||
| 16 | typedef unsigned short __kernel_uid_t; | ||
| 17 | typedef unsigned short __kernel_gid_t; | ||
| 18 | typedef unsigned int __kernel_size_t; | ||
| 19 | typedef int __kernel_ssize_t; | ||
| 20 | typedef int __kernel_ptrdiff_t; | ||
| 21 | typedef long __kernel_time_t; | ||
| 22 | typedef long __kernel_suseconds_t; | ||
| 23 | typedef long __kernel_clock_t; | ||
| 24 | typedef int __kernel_timer_t; | ||
| 25 | typedef int __kernel_clockid_t; | ||
| 26 | typedef int __kernel_daddr_t; | ||
| 27 | typedef char * __kernel_caddr_t; | ||
| 28 | typedef unsigned short __kernel_uid16_t; | ||
| 29 | typedef unsigned short __kernel_gid16_t; | ||
| 30 | typedef unsigned int __kernel_uid32_t; | ||
| 31 | typedef unsigned int __kernel_gid32_t; | ||
| 32 | |||
| 33 | typedef unsigned short __kernel_old_uid_t; | ||
| 34 | typedef unsigned short __kernel_old_gid_t; | ||
| 35 | typedef unsigned short __kernel_old_dev_t; | ||
| 36 | |||
| 37 | #ifdef __GNUC__ | ||
| 38 | typedef long long __kernel_loff_t; | ||
| 39 | #endif | ||
| 40 | |||
| 41 | typedef struct { | ||
| 42 | int val[2]; | ||
| 43 | } __kernel_fsid_t; | ||
| 44 | |||
| 45 | #if defined(__KERNEL__) | ||
| 46 | |||
| 47 | #undef __FD_SET | ||
| 48 | #define __FD_SET(fd,fdsetp) \ | ||
| 49 | asm volatile("btsl %1,%0": \ | ||
| 50 | "+m" (*(__kernel_fd_set *)(fdsetp)) \ | ||
| 51 | : "r" ((int)(fd))) | ||
| 52 | |||
| 53 | #undef __FD_CLR | ||
| 54 | #define __FD_CLR(fd,fdsetp) \ | ||
| 55 | asm volatile("btrl %1,%0": \ | ||
| 56 | "+m" (*(__kernel_fd_set *)(fdsetp)) \ | ||
| 57 | : "r" ((int) (fd))) | ||
| 58 | |||
| 59 | #undef __FD_ISSET | ||
| 60 | #define __FD_ISSET(fd,fdsetp) \ | ||
| 61 | (__extension__ \ | ||
| 62 | ({ \ | ||
| 63 | unsigned char __result; \ | ||
| 64 | asm volatile("btl %1,%2 ; setb %0" \ | ||
| 65 | : "=q" (__result) \ | ||
| 66 | : "r" ((int)(fd)), \ | ||
| 67 | "m" (*(__kernel_fd_set *)(fdsetp))); \ | ||
| 68 | __result; \ | ||
| 69 | })) | ||
| 70 | |||
| 71 | #undef __FD_ZERO | ||
| 72 | #define __FD_ZERO(fdsetp) \ | ||
| 73 | do { \ | ||
| 74 | int __d0, __d1; \ | ||
| 75 | asm volatile("cld ; rep ; stosl" \ | ||
| 76 | : "=m" (*(__kernel_fd_set *)(fdsetp)), \ | ||
| 77 | "=&c" (__d0), "=&D" (__d1) \ | ||
| 78 | : "a" (0), "1" (__FDSET_LONGS), \ | ||
| 79 | "2" ((__kernel_fd_set *)(fdsetp)) \ | ||
| 80 | : "memory"); \ | ||
| 81 | } while (0) | ||
| 82 | |||
| 83 | #endif /* defined(__KERNEL__) */ | ||
| 84 | |||
| 85 | #endif /* _ASM_X86_POSIX_TYPES_32_H */ | ||
diff --git a/arch/x86/include/asm/posix_types_64.h b/arch/x86/include/asm/posix_types_64.h new file mode 100644 index 00000000000..eb8d2d92b63 --- /dev/null +++ b/arch/x86/include/asm/posix_types_64.h | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | #ifndef _ASM_X86_POSIX_TYPES_64_H | ||
| 2 | #define _ASM_X86_POSIX_TYPES_64_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * This file is generally used by user-level software, so you need to | ||
| 6 | * be a little careful about namespace pollution etc. Also, we cannot | ||
| 7 | * assume GCC is being used. | ||
| 8 | */ | ||
| 9 | |||
| 10 | typedef unsigned long __kernel_ino_t; | ||
| 11 | typedef unsigned int __kernel_mode_t; | ||
| 12 | typedef unsigned long __kernel_nlink_t; | ||
| 13 | typedef long __kernel_off_t; | ||
| 14 | typedef int __kernel_pid_t; | ||
| 15 | typedef int __kernel_ipc_pid_t; | ||
| 16 | typedef unsigned int __kernel_uid_t; | ||
| 17 | typedef unsigned int __kernel_gid_t; | ||
| 18 | typedef unsigned long __kernel_size_t; | ||
| 19 | typedef long __kernel_ssize_t; | ||
| 20 | typedef long __kernel_ptrdiff_t; | ||
| 21 | typedef long __kernel_time_t; | ||
| 22 | typedef long __kernel_suseconds_t; | ||
| 23 | typedef long __kernel_clock_t; | ||
| 24 | typedef int __kernel_timer_t; | ||
| 25 | typedef int __kernel_clockid_t; | ||
| 26 | typedef int __kernel_daddr_t; | ||
| 27 | typedef char * __kernel_caddr_t; | ||
| 28 | typedef unsigned short __kernel_uid16_t; | ||
| 29 | typedef unsigned short __kernel_gid16_t; | ||
| 30 | |||
| 31 | #ifdef __GNUC__ | ||
| 32 | typedef long long __kernel_loff_t; | ||
| 33 | #endif | ||
| 34 | |||
| 35 | typedef struct { | ||
| 36 | int val[2]; | ||
| 37 | } __kernel_fsid_t; | ||
| 38 | |||
| 39 | typedef unsigned short __kernel_old_uid_t; | ||
| 40 | typedef unsigned short __kernel_old_gid_t; | ||
| 41 | typedef __kernel_uid_t __kernel_uid32_t; | ||
| 42 | typedef __kernel_gid_t __kernel_gid32_t; | ||
| 43 | |||
| 44 | typedef unsigned long __kernel_old_dev_t; | ||
| 45 | |||
| 46 | #ifdef __KERNEL__ | ||
| 47 | |||
| 48 | #undef __FD_SET | ||
| 49 | static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) | ||
| 50 | { | ||
| 51 | unsigned long _tmp = fd / __NFDBITS; | ||
| 52 | unsigned long _rem = fd % __NFDBITS; | ||
| 53 | fdsetp->fds_bits[_tmp] |= (1UL<<_rem); | ||
| 54 | } | ||
| 55 | |||
| 56 | #undef __FD_CLR | ||
| 57 | static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) | ||
| 58 | { | ||
| 59 | unsigned long _tmp = fd / __NFDBITS; | ||
| 60 | unsigned long _rem = fd % __NFDBITS; | ||
| 61 | fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); | ||
| 62 | } | ||
| 63 | |||
| 64 | #undef __FD_ISSET | ||
| 65 | static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) | ||
| 66 | { | ||
| 67 | unsigned long _tmp = fd / __NFDBITS; | ||
| 68 | unsigned long _rem = fd % __NFDBITS; | ||
| 69 | return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | * This will unroll the loop for the normal constant cases (8 or 32 longs, | ||
| 74 | * for 256 and 1024-bit fd_sets respectively) | ||
| 75 | */ | ||
| 76 | #undef __FD_ZERO | ||
| 77 | static inline void __FD_ZERO(__kernel_fd_set *p) | ||
| 78 | { | ||
| 79 | unsigned long *tmp = p->fds_bits; | ||
| 80 | int i; | ||
| 81 | |||
| 82 | if (__builtin_constant_p(__FDSET_LONGS)) { | ||
| 83 | switch (__FDSET_LONGS) { | ||
| 84 | case 32: | ||
| 85 | tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; | ||
| 86 | tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; | ||
| 87 | tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; | ||
| 88 | tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; | ||
| 89 | tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0; | ||
| 90 | tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0; | ||
| 91 | tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0; | ||
| 92 | tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0; | ||
| 93 | return; | ||
| 94 | case 16: | ||
| 95 | tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; | ||
| 96 | tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; | ||
| 97 | tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; | ||
| 98 | tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; | ||
| 99 | return; | ||
| 100 | case 8: | ||
| 101 | tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; | ||
| 102 | tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; | ||
| 103 | return; | ||
| 104 | case 4: | ||
| 105 | tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; | ||
| 106 | return; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | i = __FDSET_LONGS; | ||
| 110 | while (i) { | ||
| 111 | i--; | ||
| 112 | *tmp = 0; | ||
| 113 | tmp++; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | #endif /* defined(__KERNEL__) */ | ||
| 118 | |||
| 119 | #endif /* _ASM_X86_POSIX_TYPES_64_H */ | ||
diff --git a/arch/x86/include/asm/prctl.h b/arch/x86/include/asm/prctl.h new file mode 100644 index 00000000000..3ac5032fae0 --- /dev/null +++ b/arch/x86/include/asm/prctl.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | #ifndef _ASM_X86_PRCTL_H | ||
| 2 | #define _ASM_X86_PRCTL_H | ||
| 3 | |||
| 4 | #define ARCH_SET_GS 0x1001 | ||
| 5 | #define ARCH_SET_FS 0x1002 | ||
| 6 | #define ARCH_GET_FS 0x1003 | ||
| 7 | #define ARCH_GET_GS 0x1004 | ||
| 8 | |||
| 9 | #endif /* _ASM_X86_PRCTL_H */ | ||
diff --git a/arch/x86/include/asm/ptrace-abi.h b/arch/x86/include/asm/ptrace-abi.h new file mode 100644 index 00000000000..7b0a55a8885 --- /dev/null +++ b/arch/x86/include/asm/ptrace-abi.h | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | #ifndef _ASM_X86_PTRACE_ABI_H | ||
| 2 | #define _ASM_X86_PTRACE_ABI_H | ||
| 3 | |||
| 4 | #ifdef __i386__ | ||
| 5 | |||
| 6 | #define EBX 0 | ||
| 7 | #define ECX 1 | ||
| 8 | #define EDX 2 | ||
| 9 | #define ESI 3 | ||
| 10 | #define EDI 4 | ||
| 11 | #define EBP 5 | ||
| 12 | #define EAX 6 | ||
| 13 | #define DS 7 | ||
| 14 | #define ES 8 | ||
| 15 | #define FS 9 | ||
| 16 | #define GS 10 | ||
| 17 | #define ORIG_EAX 11 | ||
| 18 | #define EIP 12 | ||
| 19 | #define CS 13 | ||
| 20 | #define EFL 14 | ||
| 21 | #define UESP 15 | ||
| 22 | #define SS 16 | ||
| 23 | #define FRAME_SIZE 17 | ||
| 24 | |||
| 25 | #else /* __i386__ */ | ||
| 26 | |||
| 27 | #if defined(__ASSEMBLY__) || defined(__FRAME_OFFSETS) | ||
| 28 | #define R15 0 | ||
| 29 | #define R14 8 | ||
| 30 | #define R13 16 | ||
| 31 | #define R12 24 | ||
| 32 | #define RBP 32 | ||
| 33 | #define RBX 40 | ||
| 34 | /* arguments: interrupts/non tracing syscalls only save up to here*/ | ||
| 35 | #define R11 48 | ||
| 36 | #define R10 56 | ||
| 37 | #define R9 64 | ||
| 38 | #define R8 72 | ||
| 39 | #define RAX 80 | ||
| 40 | #define RCX 88 | ||
| 41 | #define RDX 96 | ||
| 42 | #define RSI 104 | ||
| 43 | #define RDI 112 | ||
| 44 | #define ORIG_RAX 120 /* = ERROR */ | ||
| 45 | /* end of arguments */ | ||
| 46 | /* cpu exception frame or undefined in case of fast syscall. */ | ||
| 47 | #define RIP 128 | ||
| 48 | #define CS 136 | ||
| 49 | #define EFLAGS 144 | ||
| 50 | #define RSP 152 | ||
| 51 | #define SS 160 | ||
| 52 | #define ARGOFFSET R11 | ||
| 53 | #endif /* __ASSEMBLY__ */ | ||
| 54 | |||
| 55 | /* top of stack page */ | ||
| 56 | #define FRAME_SIZE 168 | ||
| 57 | |||
| 58 | #endif /* !__i386__ */ | ||
| 59 | |||
| 60 | /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ | ||
| 61 | #define PTRACE_GETREGS 12 | ||
| 62 | #define PTRACE_SETREGS 13 | ||
| 63 | #define PTRACE_GETFPREGS 14 | ||
| 64 | #define PTRACE_SETFPREGS 15 | ||
| 65 | #define PTRACE_GETFPXREGS 18 | ||
| 66 | #define PTRACE_SETFPXREGS 19 | ||
| 67 | |||
| 68 | #define PTRACE_OLDSETOPTIONS 21 | ||
| 69 | |||
| 70 | /* only useful for access 32bit programs / kernels */ | ||
| 71 | #define PTRACE_GET_THREAD_AREA 25 | ||
| 72 | #define PTRACE_SET_THREAD_AREA 26 | ||
| 73 | |||
| 74 | #ifdef __x86_64__ | ||
| 75 | # define PTRACE_ARCH_PRCTL 30 | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #define PTRACE_SYSEMU 31 | ||
| 79 | #define PTRACE_SYSEMU_SINGLESTEP 32 | ||
| 80 | |||
| 81 | #define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */ | ||
| 82 | |||
| 83 | #ifndef __ASSEMBLY__ | ||
| 84 | #include <linux/types.h> | ||
| 85 | #endif | ||
| 86 | |||
| 87 | #endif /* _ASM_X86_PTRACE_ABI_H */ | ||
diff --git a/arch/x86/include/asm/resource.h b/arch/x86/include/asm/resource.h new file mode 100644 index 00000000000..04bc4db8921 --- /dev/null +++ b/arch/x86/include/asm/resource.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/resource.h> | |||
diff --git a/arch/x86/include/asm/sembuf.h b/arch/x86/include/asm/sembuf.h new file mode 100644 index 00000000000..ee50c801f7b --- /dev/null +++ b/arch/x86/include/asm/sembuf.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #ifndef _ASM_X86_SEMBUF_H | ||
| 2 | #define _ASM_X86_SEMBUF_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * The semid64_ds structure for x86 architecture. | ||
| 6 | * Note extra padding because this structure is passed back and forth | ||
| 7 | * between kernel and user space. | ||
| 8 | * | ||
| 9 | * Pad space is left for: | ||
| 10 | * - 64-bit time_t to solve y2038 problem | ||
| 11 | * - 2 miscellaneous 32-bit values | ||
| 12 | */ | ||
| 13 | struct semid64_ds { | ||
| 14 | struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ | ||
| 15 | __kernel_time_t sem_otime; /* last semop time */ | ||
| 16 | unsigned long __unused1; | ||
| 17 | __kernel_time_t sem_ctime; /* last change time */ | ||
| 18 | unsigned long __unused2; | ||
| 19 | unsigned long sem_nsems; /* no. of semaphores in array */ | ||
| 20 | unsigned long __unused3; | ||
| 21 | unsigned long __unused4; | ||
| 22 | }; | ||
| 23 | |||
| 24 | #endif /* _ASM_X86_SEMBUF_H */ | ||
diff --git a/arch/x86/include/asm/shmbuf.h b/arch/x86/include/asm/shmbuf.h new file mode 100644 index 00000000000..83c05fc2de3 --- /dev/null +++ b/arch/x86/include/asm/shmbuf.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/shmbuf.h> | |||
diff --git a/arch/x86/include/asm/sigcontext32.h b/arch/x86/include/asm/sigcontext32.h new file mode 100644 index 00000000000..ad1478c4ae1 --- /dev/null +++ b/arch/x86/include/asm/sigcontext32.h | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | #ifndef _ASM_X86_SIGCONTEXT32_H | ||
| 2 | #define _ASM_X86_SIGCONTEXT32_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | |||
| 6 | /* signal context for 32bit programs. */ | ||
| 7 | |||
| 8 | #define X86_FXSR_MAGIC 0x0000 | ||
| 9 | |||
| 10 | struct _fpreg { | ||
| 11 | unsigned short significand[4]; | ||
| 12 | unsigned short exponent; | ||
| 13 | }; | ||
| 14 | |||
| 15 | struct _fpxreg { | ||
| 16 | unsigned short significand[4]; | ||
| 17 | unsigned short exponent; | ||
| 18 | unsigned short padding[3]; | ||
| 19 | }; | ||
| 20 | |||
| 21 | struct _xmmreg { | ||
| 22 | __u32 element[4]; | ||
| 23 | }; | ||
| 24 | |||
| 25 | /* FSAVE frame with extensions */ | ||
| 26 | struct _fpstate_ia32 { | ||
| 27 | /* Regular FPU environment */ | ||
| 28 | __u32 cw; | ||
| 29 | __u32 sw; | ||
| 30 | __u32 tag; /* not compatible to 64bit twd */ | ||
| 31 | __u32 ipoff; | ||
| 32 | __u32 cssel; | ||
| 33 | __u32 dataoff; | ||
| 34 | __u32 datasel; | ||
| 35 | struct _fpreg _st[8]; | ||
| 36 | unsigned short status; | ||
| 37 | unsigned short magic; /* 0xffff = regular FPU data only */ | ||
| 38 | |||
| 39 | /* FXSR FPU environment */ | ||
| 40 | __u32 _fxsr_env[6]; | ||
| 41 | __u32 mxcsr; | ||
| 42 | __u32 reserved; | ||
| 43 | struct _fpxreg _fxsr_st[8]; | ||
| 44 | struct _xmmreg _xmm[8]; /* It's actually 16 */ | ||
| 45 | __u32 padding[44]; | ||
| 46 | union { | ||
| 47 | __u32 padding2[12]; | ||
| 48 | struct _fpx_sw_bytes sw_reserved; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 52 | struct sigcontext_ia32 { | ||
| 53 | unsigned short gs, __gsh; | ||
| 54 | unsigned short fs, __fsh; | ||
| 55 | unsigned short es, __esh; | ||
| 56 | unsigned short ds, __dsh; | ||
| 57 | unsigned int di; | ||
| 58 | unsigned int si; | ||
| 59 | unsigned int bp; | ||
| 60 | unsigned int sp; | ||
| 61 | unsigned int bx; | ||
| 62 | unsigned int dx; | ||
| 63 | unsigned int cx; | ||
| 64 | unsigned int ax; | ||
| 65 | unsigned int trapno; | ||
| 66 | unsigned int err; | ||
| 67 | unsigned int ip; | ||
| 68 | unsigned short cs, __csh; | ||
| 69 | unsigned int flags; | ||
| 70 | unsigned int sp_at_signal; | ||
| 71 | unsigned short ss, __ssh; | ||
| 72 | unsigned int fpstate; /* really (struct _fpstate_ia32 *) */ | ||
| 73 | unsigned int oldmask; | ||
| 74 | unsigned int cr2; | ||
| 75 | }; | ||
| 76 | |||
| 77 | #endif /* _ASM_X86_SIGCONTEXT32_H */ | ||
diff --git a/arch/x86/include/asm/siginfo.h b/arch/x86/include/asm/siginfo.h new file mode 100644 index 00000000000..fc1aa553564 --- /dev/null +++ b/arch/x86/include/asm/siginfo.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #ifndef _ASM_X86_SIGINFO_H | ||
| 2 | #define _ASM_X86_SIGINFO_H | ||
| 3 | |||
| 4 | #ifdef __x86_64__ | ||
| 5 | # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
| 6 | #endif | ||
| 7 | |||
| 8 | #include <asm-generic/siginfo.h> | ||
| 9 | |||
| 10 | #endif /* _ASM_X86_SIGINFO_H */ | ||
diff --git a/arch/x86/include/asm/socket.h b/arch/x86/include/asm/socket.h new file mode 100644 index 00000000000..6b71384b9d8 --- /dev/null +++ b/arch/x86/include/asm/socket.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/socket.h> | |||
diff --git a/arch/x86/include/asm/sockios.h b/arch/x86/include/asm/sockios.h new file mode 100644 index 00000000000..def6d4746ee --- /dev/null +++ b/arch/x86/include/asm/sockios.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/sockios.h> | |||
diff --git a/arch/x86/include/asm/stat.h b/arch/x86/include/asm/stat.h new file mode 100644 index 00000000000..e0b1d9bbcbc --- /dev/null +++ b/arch/x86/include/asm/stat.h | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | #ifndef _ASM_X86_STAT_H | ||
| 2 | #define _ASM_X86_STAT_H | ||
| 3 | |||
| 4 | #define STAT_HAVE_NSEC 1 | ||
| 5 | |||
| 6 | #ifdef __i386__ | ||
| 7 | struct stat { | ||
| 8 | unsigned long st_dev; | ||
| 9 | unsigned long st_ino; | ||
| 10 | unsigned short st_mode; | ||
| 11 | unsigned short st_nlink; | ||
| 12 | unsigned short st_uid; | ||
| 13 | unsigned short st_gid; | ||
| 14 | unsigned long st_rdev; | ||
| 15 | unsigned long st_size; | ||
| 16 | unsigned long st_blksize; | ||
| 17 | unsigned long st_blocks; | ||
| 18 | unsigned long st_atime; | ||
| 19 | unsigned long st_atime_nsec; | ||
| 20 | unsigned long st_mtime; | ||
| 21 | unsigned long st_mtime_nsec; | ||
| 22 | unsigned long st_ctime; | ||
| 23 | unsigned long st_ctime_nsec; | ||
| 24 | unsigned long __unused4; | ||
| 25 | unsigned long __unused5; | ||
| 26 | }; | ||
| 27 | |||
| 28 | #define STAT64_HAS_BROKEN_ST_INO 1 | ||
| 29 | |||
| 30 | /* This matches struct stat64 in glibc2.1, hence the absolutely | ||
| 31 | * insane amounts of padding around dev_t's. | ||
| 32 | */ | ||
| 33 | struct stat64 { | ||
| 34 | unsigned long long st_dev; | ||
| 35 | unsigned char __pad0[4]; | ||
| 36 | |||
| 37 | unsigned long __st_ino; | ||
| 38 | |||
| 39 | unsigned int st_mode; | ||
| 40 | unsigned int st_nlink; | ||
| 41 | |||
| 42 | unsigned long st_uid; | ||
| 43 | unsigned long st_gid; | ||
| 44 | |||
| 45 | unsigned long long st_rdev; | ||
| 46 | unsigned char __pad3[4]; | ||
| 47 | |||
| 48 | long long st_size; | ||
| 49 | unsigned long st_blksize; | ||
| 50 | |||
| 51 | /* Number 512-byte blocks allocated. */ | ||
| 52 | unsigned long long st_blocks; | ||
| 53 | |||
| 54 | unsigned long st_atime; | ||
| 55 | unsigned long st_atime_nsec; | ||
| 56 | |||
| 57 | unsigned long st_mtime; | ||
| 58 | unsigned int st_mtime_nsec; | ||
| 59 | |||
| 60 | unsigned long st_ctime; | ||
| 61 | unsigned long st_ctime_nsec; | ||
| 62 | |||
| 63 | unsigned long long st_ino; | ||
| 64 | }; | ||
| 65 | |||
| 66 | #else /* __i386__ */ | ||
| 67 | |||
| 68 | struct stat { | ||
| 69 | unsigned long st_dev; | ||
| 70 | unsigned long st_ino; | ||
| 71 | unsigned long st_nlink; | ||
| 72 | |||
| 73 | unsigned int st_mode; | ||
| 74 | unsigned int st_uid; | ||
| 75 | unsigned int st_gid; | ||
| 76 | unsigned int __pad0; | ||
| 77 | unsigned long st_rdev; | ||
| 78 | long st_size; | ||
| 79 | long st_blksize; | ||
| 80 | long st_blocks; /* Number 512-byte blocks allocated. */ | ||
| 81 | |||
| 82 | unsigned long st_atime; | ||
| 83 | unsigned long st_atime_nsec; | ||
| 84 | unsigned long st_mtime; | ||
| 85 | unsigned long st_mtime_nsec; | ||
| 86 | unsigned long st_ctime; | ||
| 87 | unsigned long st_ctime_nsec; | ||
| 88 | long __unused[3]; | ||
| 89 | }; | ||
| 90 | #endif | ||
| 91 | |||
| 92 | /* for 32bit emulation and 32 bit kernels */ | ||
| 93 | struct __old_kernel_stat { | ||
| 94 | unsigned short st_dev; | ||
| 95 | unsigned short st_ino; | ||
| 96 | unsigned short st_mode; | ||
| 97 | unsigned short st_nlink; | ||
| 98 | unsigned short st_uid; | ||
| 99 | unsigned short st_gid; | ||
| 100 | unsigned short st_rdev; | ||
| 101 | #ifdef __i386__ | ||
| 102 | unsigned long st_size; | ||
| 103 | unsigned long st_atime; | ||
| 104 | unsigned long st_mtime; | ||
| 105 | unsigned long st_ctime; | ||
| 106 | #else | ||
| 107 | unsigned int st_size; | ||
| 108 | unsigned int st_atime; | ||
| 109 | unsigned int st_mtime; | ||
| 110 | unsigned int st_ctime; | ||
| 111 | #endif | ||
| 112 | }; | ||
| 113 | |||
| 114 | #endif /* _ASM_X86_STAT_H */ | ||
diff --git a/arch/x86/include/asm/statfs.h b/arch/x86/include/asm/statfs.h new file mode 100644 index 00000000000..2d0adbf99a8 --- /dev/null +++ b/arch/x86/include/asm/statfs.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef _ASM_X86_STATFS_H | ||
| 2 | #define _ASM_X86_STATFS_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * We need compat_statfs64 to be packed, because the i386 ABI won't | ||
| 6 | * add padding at the end to bring it to a multiple of 8 bytes, but | ||
| 7 | * the x86_64 ABI will. | ||
| 8 | */ | ||
| 9 | #define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4))) | ||
| 10 | |||
| 11 | #include <asm-generic/statfs.h> | ||
| 12 | #endif /* _ASM_X86_STATFS_H */ | ||
diff --git a/arch/x86/include/asm/swab.h b/arch/x86/include/asm/swab.h new file mode 100644 index 00000000000..557cd9f0066 --- /dev/null +++ b/arch/x86/include/asm/swab.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | #ifndef _ASM_X86_SWAB_H | ||
| 2 | #define _ASM_X86_SWAB_H | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | #include <linux/compiler.h> | ||
| 6 | |||
| 7 | static inline __attribute_const__ __u32 __arch_swab32(__u32 val) | ||
| 8 | { | ||
| 9 | #ifdef __i386__ | ||
| 10 | # ifdef CONFIG_X86_BSWAP | ||
| 11 | asm("bswap %0" : "=r" (val) : "0" (val)); | ||
| 12 | # else | ||
| 13 | asm("xchgb %b0,%h0\n\t" /* swap lower bytes */ | ||
| 14 | "rorl $16,%0\n\t" /* swap words */ | ||
| 15 | "xchgb %b0,%h0" /* swap higher bytes */ | ||
| 16 | : "=q" (val) | ||
| 17 | : "0" (val)); | ||
| 18 | # endif | ||
| 19 | |||
| 20 | #else /* __i386__ */ | ||
| 21 | asm("bswapl %0" | ||
| 22 | : "=r" (val) | ||
| 23 | : "0" (val)); | ||
| 24 | #endif | ||
| 25 | return val; | ||
| 26 | } | ||
| 27 | #define __arch_swab32 __arch_swab32 | ||
| 28 | |||
| 29 | static inline __attribute_const__ __u64 __arch_swab64(__u64 val) | ||
| 30 | { | ||
| 31 | #ifdef __i386__ | ||
| 32 | union { | ||
| 33 | struct { | ||
| 34 | __u32 a; | ||
| 35 | __u32 b; | ||
| 36 | } s; | ||
| 37 | __u64 u; | ||
| 38 | } v; | ||
| 39 | v.u = val; | ||
| 40 | # ifdef CONFIG_X86_BSWAP | ||
| 41 | asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" | ||
| 42 | : "=r" (v.s.a), "=r" (v.s.b) | ||
| 43 | : "0" (v.s.a), "1" (v.s.b)); | ||
| 44 | # else | ||
| 45 | v.s.a = __arch_swab32(v.s.a); | ||
| 46 | v.s.b = __arch_swab32(v.s.b); | ||
| 47 | asm("xchgl %0,%1" | ||
| 48 | : "=r" (v.s.a), "=r" (v.s.b) | ||
| 49 | : "0" (v.s.a), "1" (v.s.b)); | ||
| 50 | # endif | ||
| 51 | return v.u; | ||
| 52 | #else /* __i386__ */ | ||
| 53 | asm("bswapq %0" | ||
| 54 | : "=r" (val) | ||
| 55 | : "0" (val)); | ||
| 56 | return val; | ||
| 57 | #endif | ||
| 58 | } | ||
| 59 | #define __arch_swab64 __arch_swab64 | ||
| 60 | |||
| 61 | #endif /* _ASM_X86_SWAB_H */ | ||
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h new file mode 100644 index 00000000000..2d2f01ce6dc --- /dev/null +++ b/arch/x86/include/asm/system.h | |||
| @@ -0,0 +1,523 @@ | |||
| 1 | #ifndef _ASM_X86_SYSTEM_H | ||
| 2 | #define _ASM_X86_SYSTEM_H | ||
| 3 | |||
| 4 | #include <asm/asm.h> | ||
| 5 | #include <asm/segment.h> | ||
| 6 | #include <asm/cpufeature.h> | ||
| 7 | #include <asm/cmpxchg.h> | ||
| 8 | #include <asm/nops.h> | ||
| 9 | |||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/irqflags.h> | ||
| 12 | |||
| 13 | /* entries in ARCH_DLINFO: */ | ||
| 14 | #if defined(CONFIG_IA32_EMULATION) || !defined(CONFIG_X86_64) | ||
| 15 | # define AT_VECTOR_SIZE_ARCH 2 | ||
| 16 | #else /* else it's non-compat x86-64 */ | ||
| 17 | # define AT_VECTOR_SIZE_ARCH 1 | ||
| 18 | #endif | ||
| 19 | |||
| 20 | struct task_struct; /* one of the stranger aspects of C forward declarations */ | ||
| 21 | struct task_struct *__switch_to(struct task_struct *prev, | ||
| 22 | struct task_struct *next); | ||
| 23 | struct tss_struct; | ||
| 24 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | ||
| 25 | struct tss_struct *tss); | ||
| 26 | extern void show_regs_common(void); | ||
| 27 | |||
| 28 | #ifdef CONFIG_X86_32 | ||
| 29 | |||
| 30 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
| 31 | #define __switch_canary \ | ||
| 32 | "movl %P[task_canary](%[next]), %%ebx\n\t" \ | ||
| 33 | "movl %%ebx, "__percpu_arg([stack_canary])"\n\t" | ||
| 34 | #define __switch_canary_oparam \ | ||
| 35 | , [stack_canary] "=m" (stack_canary.canary) | ||
| 36 | #define __switch_canary_iparam \ | ||
| 37 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) | ||
| 38 | #else /* CC_STACKPROTECTOR */ | ||
| 39 | #define __switch_canary | ||
| 40 | #define __switch_canary_oparam | ||
| 41 | #define __switch_canary_iparam | ||
| 42 | #endif /* CC_STACKPROTECTOR */ | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Saving eflags is important. It switches not only IOPL between tasks, | ||
| 46 | * it also protects other tasks from NT leaking through sysenter etc. | ||
| 47 | */ | ||
| 48 | #define switch_to(prev, next, last) \ | ||
| 49 | do { \ | ||
| 50 | /* \ | ||
| 51 | * Context-switching clobbers all registers, so we clobber \ | ||
| 52 | * them explicitly, via unused output variables. \ | ||
| 53 | * (EAX and EBP is not listed because EBP is saved/restored \ | ||
| 54 | * explicitly for wchan access and EAX is the return value of \ | ||
| 55 | * __switch_to()) \ | ||
| 56 | */ \ | ||
| 57 | unsigned long ebx, ecx, edx, esi, edi; \ | ||
| 58 | \ | ||
| 59 | asm volatile("pushfl\n\t" /* save flags */ \ | ||
| 60 | "pushl %%ebp\n\t" /* save EBP */ \ | ||
| 61 | "movl %%esp,%[prev_sp]\n\t" /* save ESP */ \ | ||
| 62 | "movl %[next_sp],%%esp\n\t" /* restore ESP */ \ | ||
| 63 | "movl $1f,%[prev_ip]\n\t" /* save EIP */ \ | ||
| 64 | "pushl %[next_ip]\n\t" /* restore EIP */ \ | ||
| 65 | __switch_canary \ | ||
| 66 | "jmp __switch_to\n" /* regparm call */ \ | ||
| 67 | "1:\t" \ | ||
| 68 | "popl %%ebp\n\t" /* restore EBP */ \ | ||
| 69 | "popfl\n" /* restore flags */ \ | ||
| 70 | \ | ||
| 71 | /* output parameters */ \ | ||
| 72 | : [prev_sp] "=m" (prev->thread.sp), \ | ||
| 73 | [prev_ip] "=m" (prev->thread.ip), \ | ||
| 74 | "=a" (last), \ | ||
| 75 | \ | ||
| 76 | /* clobbered output registers: */ \ | ||
| 77 | "=b" (ebx), "=c" (ecx), "=d" (edx), \ | ||
| 78 | "=S" (esi), "=D" (edi) \ | ||
| 79 | \ | ||
| 80 | __switch_canary_oparam \ | ||
| 81 | \ | ||
| 82 | /* input parameters: */ \ | ||
| 83 | : [next_sp] "m" (next->thread.sp), \ | ||
| 84 | [next_ip] "m" (next->thread.ip), \ | ||
| 85 | \ | ||
| 86 | /* regparm parameters for __switch_to(): */ \ | ||
| 87 | [prev] "a" (prev), \ | ||
| 88 | [next] "d" (next) \ | ||
| 89 | \ | ||
| 90 | __switch_canary_iparam \ | ||
| 91 | \ | ||
| 92 | : /* reloaded segment registers */ \ | ||
| 93 | "memory"); \ | ||
| 94 | } while (0) | ||
| 95 | |||
| 96 | /* | ||
| 97 | * disable hlt during certain critical i/o operations | ||
| 98 | */ | ||
| 99 | #define HAVE_DISABLE_HLT | ||
| 100 | #else | ||
| 101 | |||
| 102 | /* frame pointer must be last for get_wchan */ | ||
| 103 | #define SAVE_CONTEXT "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t" | ||
| 104 | #define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t" | ||
| 105 | |||
| 106 | #define __EXTRA_CLOBBER \ | ||
| 107 | , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \ | ||
| 108 | "r12", "r13", "r14", "r15" | ||
| 109 | |||
| 110 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
| 111 | #define __switch_canary \ | ||
| 112 | "movq %P[task_canary](%%rsi),%%r8\n\t" \ | ||
| 113 | "movq %%r8,"__percpu_arg([gs_canary])"\n\t" | ||
| 114 | #define __switch_canary_oparam \ | ||
| 115 | , [gs_canary] "=m" (irq_stack_union.stack_canary) | ||
| 116 | #define __switch_canary_iparam \ | ||
| 117 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) | ||
| 118 | #else /* CC_STACKPROTECTOR */ | ||
| 119 | #define __switch_canary | ||
| 120 | #define __switch_canary_oparam | ||
| 121 | #define __switch_canary_iparam | ||
| 122 | #endif /* CC_STACKPROTECTOR */ | ||
| 123 | |||
| 124 | /* Save restore flags to clear handle leaking NT */ | ||
| 125 | #define switch_to(prev, next, last) \ | ||
| 126 | asm volatile(SAVE_CONTEXT \ | ||
| 127 | "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ | ||
| 128 | "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ | ||
| 129 | "call __switch_to\n\t" \ | ||
| 130 | "movq "__percpu_arg([current_task])",%%rsi\n\t" \ | ||
| 131 | __switch_canary \ | ||
| 132 | "movq %P[thread_info](%%rsi),%%r8\n\t" \ | ||
| 133 | "movq %%rax,%%rdi\n\t" \ | ||
| 134 | "testl %[_tif_fork],%P[ti_flags](%%r8)\n\t" \ | ||
| 135 | "jnz ret_from_fork\n\t" \ | ||
| 136 | RESTORE_CONTEXT \ | ||
| 137 | : "=a" (last) \ | ||
| 138 | __switch_canary_oparam \ | ||
| 139 | : [next] "S" (next), [prev] "D" (prev), \ | ||
| 140 | [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ | ||
| 141 | [ti_flags] "i" (offsetof(struct thread_info, flags)), \ | ||
| 142 | [_tif_fork] "i" (_TIF_FORK), \ | ||
| 143 | [thread_info] "i" (offsetof(struct task_struct, stack)), \ | ||
| 144 | [current_task] "m" (current_task) \ | ||
| 145 | __switch_canary_iparam \ | ||
| 146 | : "memory", "cc" __EXTRA_CLOBBER) | ||
| 147 | #endif | ||
| 148 | |||
| 149 | #ifdef __KERNEL__ | ||
| 150 | |||
| 151 | extern void native_load_gs_index(unsigned); | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Load a segment. Fall back on loading the zero | ||
| 155 | * segment if something goes wrong.. | ||
| 156 | */ | ||
| 157 | #define loadsegment(seg, value) \ | ||
| 158 | do { \ | ||
| 159 | unsigned short __val = (value); \ | ||
| 160 | \ | ||
| 161 | asm volatile(" \n" \ | ||
| 162 | "1: movl %k0,%%" #seg " \n" \ | ||
| 163 | \ | ||
| 164 | ".section .fixup,\"ax\" \n" \ | ||
| 165 | "2: xorl %k0,%k0 \n" \ | ||
| 166 | " jmp 1b \n" \ | ||
| 167 | ".previous \n" \ | ||
| 168 | \ | ||
| 169 | _ASM_EXTABLE(1b, 2b) \ | ||
| 170 | \ | ||
| 171 | : "+r" (__val) : : "memory"); \ | ||
| 172 | } while (0) | ||
| 173 | |||
| 174 | /* | ||
| 175 | * Save a segment register away | ||
| 176 | */ | ||
| 177 | #define savesegment(seg, value) \ | ||
| 178 | asm("mov %%" #seg ",%0":"=r" (value) : : "memory") | ||
| 179 | |||
| 180 | /* | ||
| 181 | * x86_32 user gs accessors. | ||
| 182 | */ | ||
| 183 | #ifdef CONFIG_X86_32 | ||
| 184 | #ifdef CONFIG_X86_32_LAZY_GS | ||
| 185 | #define get_user_gs(regs) (u16)({unsigned long v; savesegment(gs, v); v;}) | ||
| 186 | #define set_user_gs(regs, v) loadsegment(gs, (unsigned long)(v)) | ||
| 187 | #define task_user_gs(tsk) ((tsk)->thread.gs) | ||
| 188 | #define lazy_save_gs(v) savesegment(gs, (v)) | ||
| 189 | #define lazy_load_gs(v) loadsegment(gs, (v)) | ||
| 190 | #else /* X86_32_LAZY_GS */ | ||
| 191 | #define get_user_gs(regs) (u16)((regs)->gs) | ||
| 192 | #define set_user_gs(regs, v) do { (regs)->gs = (v); } while (0) | ||
| 193 | #define task_user_gs(tsk) (task_pt_regs(tsk)->gs) | ||
| 194 | #define lazy_save_gs(v) do { } while (0) | ||
| 195 | #define lazy_load_gs(v) do { } while (0) | ||
| 196 | #endif /* X86_32_LAZY_GS */ | ||
| 197 | #endif /* X86_32 */ | ||
| 198 | |||
| 199 | static inline unsigned long get_limit(unsigned long segment) | ||
| 200 | { | ||
| 201 | unsigned long __limit; | ||
| 202 | asm("lsll %1,%0" : "=r" (__limit) : "r" (segment)); | ||
| 203 | return __limit + 1; | ||
| 204 | } | ||
| 205 | |||
| 206 | static inline void native_clts(void) | ||
| 207 | { | ||
| 208 | asm volatile("clts"); | ||
| 209 | } | ||
| 210 | |||
| 211 | /* | ||
| 212 | * Volatile isn't enough to prevent the compiler from reordering the | ||
| 213 | * read/write functions for the control registers and messing everything up. | ||
| 214 | * A memory clobber would solve the problem, but would prevent reordering of | ||
| 215 | * all loads stores around it, which can hurt performance. Solution is to | ||
| 216 | * use a variable and mimic reads and writes to it to enforce serialization | ||
| 217 | */ | ||
| 218 | static unsigned long __force_order; | ||
| 219 | |||
| 220 | static inline unsigned long native_read_cr0(void) | ||
| 221 | { | ||
| 222 | unsigned long val; | ||
| 223 | asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order)); | ||
| 224 | return val; | ||
| 225 | } | ||
| 226 | |||
| 227 | static inline void native_write_cr0(unsigned long val) | ||
| 228 | { | ||
| 229 | asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order)); | ||
| 230 | } | ||
| 231 | |||
| 232 | static inline unsigned long native_read_cr2(void) | ||
| 233 | { | ||
| 234 | unsigned long val; | ||
| 235 | asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order)); | ||
| 236 | return val; | ||
| 237 | } | ||
| 238 | |||
| 239 | static inline void native_write_cr2(unsigned long val) | ||
| 240 | { | ||
| 241 | asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order)); | ||
| 242 | } | ||
| 243 | |||
| 244 | static inline unsigned long native_read_cr3(void) | ||
| 245 | { | ||
| 246 | unsigned long val; | ||
| 247 | asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order)); | ||
| 248 | return val; | ||
| 249 | } | ||
| 250 | |||
| 251 | static inline void native_write_cr3(unsigned long val) | ||
| 252 | { | ||
| 253 | asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order)); | ||
| 254 | } | ||
| 255 | |||
| 256 | static inline unsigned long native_read_cr4(void) | ||
| 257 | { | ||
| 258 | unsigned long val; | ||
| 259 | asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order)); | ||
| 260 | return val; | ||
| 261 | } | ||
| 262 | |||
| 263 | static inline unsigned long native_read_cr4_safe(void) | ||
| 264 | { | ||
| 265 | unsigned long val; | ||
| 266 | /* This could fault if %cr4 does not exist. In x86_64, a cr4 always | ||
| 267 | * exists, so it will never fail. */ | ||
| 268 | #ifdef CONFIG_X86_32 | ||
| 269 | asm volatile("1: mov %%cr4, %0\n" | ||
| 270 | "2:\n" | ||
| 271 | _ASM_EXTABLE(1b, 2b) | ||
| 272 | : "=r" (val), "=m" (__force_order) : "0" (0)); | ||
| 273 | #else | ||
| 274 | val = native_read_cr4(); | ||
| 275 | #endif | ||
| 276 | return val; | ||
| 277 | } | ||
| 278 | |||
| 279 | static inline void native_write_cr4(unsigned long val) | ||
| 280 | { | ||
| 281 | asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order)); | ||
| 282 | } | ||
| 283 | |||
| 284 | #ifdef CONFIG_X86_64 | ||
| 285 | static inline unsigned long native_read_cr8(void) | ||
| 286 | { | ||
| 287 | unsigned long cr8; | ||
| 288 | asm volatile("movq %%cr8,%0" : "=r" (cr8)); | ||
| 289 | return cr8; | ||
| 290 | } | ||
| 291 | |||
| 292 | static inline void native_write_cr8(unsigned long val) | ||
| 293 | { | ||
| 294 | asm volatile("movq %0,%%cr8" :: "r" (val) : "memory"); | ||
| 295 | } | ||
| 296 | #endif | ||
| 297 | |||
| 298 | static inline void native_wbinvd(void) | ||
| 299 | { | ||
| 300 | asm volatile("wbinvd": : :"memory"); | ||
| 301 | } | ||
| 302 | |||
| 303 | #ifdef CONFIG_PARAVIRT | ||
| 304 | #include <asm/paravirt.h> | ||
| 305 | #else | ||
| 306 | |||
| 307 | static inline unsigned long read_cr0(void) | ||
| 308 | { | ||
| 309 | return native_read_cr0(); | ||
| 310 | } | ||
| 311 | |||
| 312 | static inline void write_cr0(unsigned long x) | ||
| 313 | { | ||
| 314 | native_write_cr0(x); | ||
| 315 | } | ||
| 316 | |||
| 317 | static inline unsigned long read_cr2(void) | ||
| 318 | { | ||
| 319 | return native_read_cr2(); | ||
| 320 | } | ||
| 321 | |||
| 322 | static inline void write_cr2(unsigned long x) | ||
| 323 | { | ||
| 324 | native_write_cr2(x); | ||
| 325 | } | ||
| 326 | |||
| 327 | static inline unsigned long read_cr3(void) | ||
| 328 | { | ||
| 329 | return native_read_cr3(); | ||
| 330 | } | ||
| 331 | |||
| 332 | static inline void write_cr3(unsigned long x) | ||
| 333 | { | ||
| 334 | native_write_cr3(x); | ||
| 335 | } | ||
| 336 | |||
| 337 | static inline unsigned long read_cr4(void) | ||
| 338 | { | ||
| 339 | return native_read_cr4(); | ||
| 340 | } | ||
| 341 | |||
| 342 | static inline unsigned long read_cr4_safe(void) | ||
| 343 | { | ||
| 344 | return native_read_cr4_safe(); | ||
| 345 | } | ||
| 346 | |||
| 347 | static inline void write_cr4(unsigned long x) | ||
| 348 | { | ||
| 349 | native_write_cr4(x); | ||
| 350 | } | ||
| 351 | |||
| 352 | static inline void wbinvd(void) | ||
| 353 | { | ||
| 354 | native_wbinvd(); | ||
| 355 | } | ||
| 356 | |||
| 357 | #ifdef CONFIG_X86_64 | ||
| 358 | |||
| 359 | static inline unsigned long read_cr8(void) | ||
| 360 | { | ||
| 361 | return native_read_cr8(); | ||
| 362 | } | ||
| 363 | |||
| 364 | static inline void write_cr8(unsigned long x) | ||
| 365 | { | ||
| 366 | native_write_cr8(x); | ||
| 367 | } | ||
| 368 | |||
| 369 | static inline void load_gs_index(unsigned selector) | ||
| 370 | { | ||
| 371 | native_load_gs_index(selector); | ||
| 372 | } | ||
| 373 | |||
| 374 | #endif | ||
| 375 | |||
| 376 | /* Clear the 'TS' bit */ | ||
| 377 | static inline void clts(void) | ||
| 378 | { | ||
| 379 | native_clts(); | ||
| 380 | } | ||
| 381 | |||
| 382 | #endif/* CONFIG_PARAVIRT */ | ||
| 383 | |||
| 384 | #define stts() write_cr0(read_cr0() | X86_CR0_TS) | ||
| 385 | |||
| 386 | #endif /* __KERNEL__ */ | ||
| 387 | |||
| 388 | static inline void clflush(volatile void *__p) | ||
| 389 | { | ||
| 390 | asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p)); | ||
| 391 | } | ||
| 392 | |||
| 393 | #define nop() asm volatile ("nop") | ||
| 394 | |||
| 395 | void disable_hlt(void); | ||
| 396 | void enable_hlt(void); | ||
| 397 | |||
| 398 | void cpu_idle_wait(void); | ||
| 399 | |||
| 400 | extern unsigned long arch_align_stack(unsigned long sp); | ||
| 401 | extern void free_init_pages(char *what, unsigned long begin, unsigned long end); | ||
| 402 | |||
| 403 | void default_idle(void); | ||
| 404 | bool set_pm_idle_to_default(void); | ||
| 405 | |||
| 406 | void stop_this_cpu(void *dummy); | ||
| 407 | |||
| 408 | /* | ||
| 409 | * Force strict CPU ordering. | ||
| 410 | * And yes, this is required on UP too when we're talking | ||
| 411 | * to devices. | ||
| 412 | */ | ||
| 413 | #ifdef CONFIG_X86_32 | ||
| 414 | /* | ||
| 415 | * Some non-Intel clones support out of order store. wmb() ceases to be a | ||
| 416 | * nop for these. | ||
| 417 | */ | ||
| 418 | #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) | ||
| 419 | #define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) | ||
| 420 | #define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) | ||
| 421 | #else | ||
| 422 | #define mb() asm volatile("mfence":::"memory") | ||
| 423 | #define rmb() asm volatile("lfence":::"memory") | ||
| 424 | #define wmb() asm volatile("sfence" ::: "memory") | ||
| 425 | #endif | ||
| 426 | |||
| 427 | /** | ||
| 428 | * read_barrier_depends - Flush all pending reads that subsequents reads | ||
| 429 | * depend on. | ||
| 430 | * | ||
| 431 | * No data-dependent reads from memory-like regions are ever reordered | ||
| 432 | * over this barrier. All reads preceding this primitive are guaranteed | ||
| 433 | * to access memory (but not necessarily other CPUs' caches) before any | ||
| 434 | * reads following this primitive that depend on the data return by | ||
| 435 | * any of the preceding reads. This primitive is much lighter weight than | ||
| 436 | * rmb() on most CPUs, and is never heavier weight than is | ||
| 437 | * rmb(). | ||
| 438 | * | ||
| 439 | * These ordering constraints are respected by both the local CPU | ||
| 440 | * and the compiler. | ||
| 441 | * | ||
| 442 | * Ordering is not guaranteed by anything other than these primitives, | ||
| 443 | * not even by data dependencies. See the documentation for | ||
| 444 | * memory_barrier() for examples and URLs to more information. | ||
| 445 | * | ||
| 446 | * For example, the following code would force ordering (the initial | ||
| 447 | * value of "a" is zero, "b" is one, and "p" is "&a"): | ||
| 448 | * | ||
| 449 | * <programlisting> | ||
| 450 | * CPU 0 CPU 1 | ||
| 451 | * | ||
| 452 | * b = 2; | ||
| 453 | * memory_barrier(); | ||
| 454 | * p = &b; q = p; | ||
| 455 | * read_barrier_depends(); | ||
| 456 | * d = *q; | ||
| 457 | * </programlisting> | ||
| 458 | * | ||
| 459 | * because the read of "*q" depends on the read of "p" and these | ||
| 460 | * two reads are separated by a read_barrier_depends(). However, | ||
| 461 | * the following code, with the same initial values for "a" and "b": | ||
| 462 | * | ||
| 463 | * <programlisting> | ||
| 464 | * CPU 0 CPU 1 | ||
| 465 | * | ||
| 466 | * a = 2; | ||
| 467 | * memory_barrier(); | ||
| 468 | * b = 3; y = b; | ||
| 469 | * read_barrier_depends(); | ||
| 470 | * x = a; | ||
| 471 | * </programlisting> | ||
| 472 | * | ||
| 473 | * does not enforce ordering, since there is no data dependency between | ||
| 474 | * the read of "a" and the read of "b". Therefore, on some CPUs, such | ||
| 475 | * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() | ||
| 476 | * in cases like this where there are no data dependencies. | ||
| 477 | **/ | ||
| 478 | |||
| 479 | #define read_barrier_depends() do { } while (0) | ||
| 480 | |||
| 481 | #ifdef CONFIG_SMP | ||
| 482 | #define smp_mb() mb() | ||
| 483 | #ifdef CONFIG_X86_PPRO_FENCE | ||
| 484 | # define smp_rmb() rmb() | ||
| 485 | #else | ||
| 486 | # define smp_rmb() barrier() | ||
| 487 | #endif | ||
| 488 | #ifdef CONFIG_X86_OOSTORE | ||
| 489 | # define smp_wmb() wmb() | ||
| 490 | #else | ||
| 491 | # define smp_wmb() barrier() | ||
| 492 | #endif | ||
| 493 | #define smp_read_barrier_depends() read_barrier_depends() | ||
| 494 | #define set_mb(var, value) do { (void)xchg(&var, value); } while (0) | ||
| 495 | #else | ||
| 496 | #define smp_mb() barrier() | ||
| 497 | #define smp_rmb() barrier() | ||
| 498 | #define smp_wmb() barrier() | ||
| 499 | #define smp_read_barrier_depends() do { } while (0) | ||
| 500 | #define set_mb(var, value) do { var = value; barrier(); } while (0) | ||
| 501 | #endif | ||
| 502 | |||
| 503 | /* | ||
| 504 | * Stop RDTSC speculation. This is needed when you need to use RDTSC | ||
| 505 | * (or get_cycles or vread that possibly accesses the TSC) in a defined | ||
| 506 | * code region. | ||
| 507 | * | ||
| 508 | * (Could use an alternative three way for this if there was one.) | ||
| 509 | */ | ||
| 510 | static __always_inline void rdtsc_barrier(void) | ||
| 511 | { | ||
| 512 | alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); | ||
| 513 | alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); | ||
| 514 | } | ||
| 515 | |||
| 516 | /* | ||
| 517 | * We handle most unaligned accesses in hardware. On the other hand | ||
| 518 | * unaligned DMA can be quite expensive on some Nehalem processors. | ||
| 519 | * | ||
| 520 | * Based on this we disable the IP header alignment in network drivers. | ||
| 521 | */ | ||
| 522 | #define NET_IP_ALIGN 0 | ||
| 523 | #endif /* _ASM_X86_SYSTEM_H */ | ||
diff --git a/arch/x86/include/asm/termbits.h b/arch/x86/include/asm/termbits.h new file mode 100644 index 00000000000..3935b106de7 --- /dev/null +++ b/arch/x86/include/asm/termbits.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/termbits.h> | |||
diff --git a/arch/x86/include/asm/termios.h b/arch/x86/include/asm/termios.h new file mode 100644 index 00000000000..280d78a9d96 --- /dev/null +++ b/arch/x86/include/asm/termios.h | |||
| @@ -0,0 +1 @@ | |||
| #include <asm-generic/termios.h> | |||
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h new file mode 100644 index 00000000000..feca3118a73 --- /dev/null +++ b/arch/x86/include/asm/trampoline.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | #ifndef _ASM_X86_TRAMPOLINE_H | ||
| 2 | #define _ASM_X86_TRAMPOLINE_H | ||
| 3 | |||
| 4 | #ifndef __ASSEMBLY__ | ||
| 5 | |||
| 6 | #include <linux/types.h> | ||
| 7 | #include <asm/io.h> | ||
| 8 | |||
| 9 | /* | ||
| 10 | * Trampoline 80x86 program as an array. These are in the init rodata | ||
| 11 | * segment, but that's okay, because we only care about the relative | ||
| 12 | * addresses of the symbols. | ||
| 13 | */ | ||
| 14 | extern const unsigned char x86_trampoline_start []; | ||
| 15 | extern const unsigned char x86_trampoline_end []; | ||
| 16 | extern unsigned char *x86_trampoline_base; | ||
| 17 | |||
| 18 | extern unsigned long init_rsp; | ||
| 19 | extern unsigned long initial_code; | ||
| 20 | extern unsigned long initial_gs; | ||
| 21 | |||
| 22 | extern void __init setup_trampolines(void); | ||
| 23 | |||
| 24 | extern const unsigned char trampoline_data[]; | ||
| 25 | extern const unsigned char trampoline_status[]; | ||
| 26 | |||
| 27 | #define TRAMPOLINE_SYM(x) \ | ||
| 28 | ((void *)(x86_trampoline_base + \ | ||
| 29 | ((const unsigned char *)(x) - x86_trampoline_start))) | ||
| 30 | |||
| 31 | /* Address of the SMP trampoline */ | ||
| 32 | static inline unsigned long trampoline_address(void) | ||
| 33 | { | ||
| 34 | return virt_to_phys(TRAMPOLINE_SYM(trampoline_data)); | ||
| 35 | } | ||
| 36 | |||
| 37 | #endif /* __ASSEMBLY__ */ | ||
| 38 | |||
| 39 | #endif /* _ASM_X86_TRAMPOLINE_H */ | ||
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h new file mode 100644 index 00000000000..8e8c23fef08 --- /dev/null +++ b/arch/x86/include/asm/types.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef _ASM_X86_TYPES_H | ||
| 2 | #define _ASM_X86_TYPES_H | ||
| 3 | |||
| 4 | #include <asm-generic/types.h> | ||
| 5 | |||
| 6 | #endif /* _ASM_X86_TYPES_H */ | ||
diff --git a/arch/x86/include/asm/ucontext.h b/arch/x86/include/asm/ucontext.h new file mode 100644 index 00000000000..b7c29c8017f --- /dev/null +++ b/arch/x86/include/asm/ucontext.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef _ASM_X86_UCONTEXT_H | ||
| 2 | #define _ASM_X86_UCONTEXT_H | ||
| 3 | |||
| 4 | #define UC_FP_XSTATE 0x1 /* indicates the presence of extended state | ||
| 5 | * information in the memory layout pointed | ||
| 6 | * by the fpstate pointer in the ucontext's | ||
| 7 | * sigcontext struct (uc_mcontext). | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <asm-generic/ucontext.h> | ||
| 11 | |||
| 12 | #endif /* _ASM_X86_UCONTEXT_H */ | ||
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h new file mode 100644 index 00000000000..593485b38ab --- /dev/null +++ b/arch/x86/include/asm/unistd_32.h | |||
| @@ -0,0 +1,399 @@ | |||
| 1 | #ifndef _ASM_X86_UNISTD_32_H | ||
| 2 | #define _ASM_X86_UNISTD_32_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * This file contains the system call numbers. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #define __NR_restart_syscall 0 | ||
| 9 | #define __NR_exit 1 | ||
| 10 | #define __NR_fork 2 | ||
| 11 | #define __NR_read 3 | ||
| 12 | #define __NR_write 4 | ||
| 13 | #define __NR_open 5 | ||
| 14 | #define __NR_close 6 | ||
| 15 | #define __NR_waitpid 7 | ||
| 16 | #define __NR_creat 8 | ||
| 17 | #define __NR_link 9 | ||
| 18 | #define __NR_unlink 10 | ||
| 19 | #define __NR_execve 11 | ||
| 20 | #define __NR_chdir 12 | ||
| 21 | #define __NR_time 13 | ||
| 22 | #define __NR_mknod 14 | ||
| 23 | #define __NR_chmod 15 | ||
| 24 | #define __NR_lchown 16 | ||
| 25 | #define __NR_break 17 | ||
| 26 | #define __NR_oldstat 18 | ||
| 27 | #define __NR_lseek 19 | ||
| 28 | #define __NR_getpid 20 | ||
| 29 | #define __NR_mount 21 | ||
| 30 | #define __NR_umount 22 | ||
| 31 | #define __NR_setuid 23 | ||
| 32 | #define __NR_getuid 24 | ||
| 33 | #define __NR_stime 25 | ||
| 34 | #define __NR_ptrace 26 | ||
| 35 | #define __NR_alarm 27 | ||
| 36 | #define __NR_oldfstat 28 | ||
| 37 | #define __NR_pause 29 | ||
| 38 | #define __NR_utime 30 | ||
| 39 | #define __NR_stty 31 | ||
| 40 | #define __NR_gtty 32 | ||
| 41 | #define __NR_access 33 | ||
| 42 | #define __NR_nice 34 | ||
| 43 | #define __NR_ftime 35 | ||
| 44 | #define __NR_sync 36 | ||
| 45 | #define __NR_kill 37 | ||
| 46 | #define __NR_rename 38 | ||
| 47 | #define __NR_mkdir 39 | ||
| 48 | #define __NR_rmdir 40 | ||
| 49 | #define __NR_dup 41 | ||
| 50 | #define __NR_pipe 42 | ||
| 51 | #define __NR_times 43 | ||
| 52 | #define __NR_prof 44 | ||
| 53 | #define __NR_brk 45 | ||
| 54 | #define __NR_setgid 46 | ||
| 55 | #define __NR_getgid 47 | ||
| 56 | #define __NR_signal 48 | ||
| 57 | #define __NR_geteuid 49 | ||
| 58 | #define __NR_getegid 50 | ||
| 59 | #define __NR_acct 51 | ||
| 60 | #define __NR_umount2 52 | ||
| 61 | #define __NR_lock 53 | ||
| 62 | #define __NR_ioctl 54 | ||
| 63 | #define __NR_fcntl 55 | ||
| 64 | #define __NR_mpx 56 | ||
| 65 | #define __NR_setpgid 57 | ||
| 66 | #define __NR_ulimit 58 | ||
| 67 | #define __NR_oldolduname 59 | ||
| 68 | #define __NR_umask 60 | ||
| 69 | #define __NR_chroot 61 | ||
| 70 | #define __NR_ustat 62 | ||
| 71 | #define __NR_dup2 63 | ||
| 72 | #define __NR_getppid 64 | ||
| 73 | #define __NR_getpgrp 65 | ||
| 74 | #define __NR_setsid 66 | ||
| 75 | #define __NR_sigaction 67 | ||
| 76 | #define __NR_sgetmask 68 | ||
| 77 | #define __NR_ssetmask 69 | ||
| 78 | #define __NR_setreuid 70 | ||
| 79 | #define __NR_setregid 71 | ||
| 80 | #define __NR_sigsuspend 72 | ||
| 81 | #define __NR_sigpending 73 | ||
| 82 | #define __NR_sethostname 74 | ||
| 83 | #define __NR_setrlimit 75 | ||
| 84 | #define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ | ||
| 85 | #define __NR_getrusage 77 | ||
| 86 | #define __NR_gettimeofday 78 | ||
| 87 | #define __NR_settimeofday 79 | ||
| 88 | #define __NR_getgroups 80 | ||
| 89 | #define __NR_setgroups 81 | ||
| 90 | #define __NR_select 82 | ||
| 91 | #define __NR_symlink 83 | ||
| 92 | #define __NR_oldlstat 84 | ||
| 93 | #define __NR_readlink 85 | ||
| 94 | #define __NR_uselib 86 | ||
| 95 | #define __NR_swapon 87 | ||
| 96 | #define __NR_reboot 88 | ||
| 97 | #define __NR_readdir 89 | ||
| 98 | #define __NR_mmap 90 | ||
| 99 | #define __NR_munmap 91 | ||
| 100 | #define __NR_truncate 92 | ||
| 101 | #define __NR_ftruncate 93 | ||
| 102 | #define __NR_fchmod 94 | ||
| 103 | #define __NR_fchown 95 | ||
| 104 | #define __NR_getpriority 96 | ||
| 105 | #define __NR_setpriority 97 | ||
| 106 | #define __NR_profil 98 | ||
| 107 | #define __NR_statfs 99 | ||
| 108 | #define __NR_fstatfs 100 | ||
| 109 | #define __NR_ioperm 101 | ||
| 110 | #define __NR_socketcall 102 | ||
| 111 | #define __NR_syslog 103 | ||
| 112 | #define __NR_setitimer 104 | ||
| 113 | #define __NR_getitimer 105 | ||
| 114 | #define __NR_stat 106 | ||
| 115 | #define __NR_lstat 107 | ||
| 116 | #define __NR_fstat 108 | ||
| 117 | #define __NR_olduname 109 | ||
| 118 | #define __NR_iopl 110 | ||
| 119 | #define __NR_vhangup 111 | ||
| 120 | #define __NR_idle 112 | ||
| 121 | #define __NR_vm86old 113 | ||
| 122 | #define __NR_wait4 114 | ||
| 123 | #define __NR_swapoff 115 | ||
| 124 | #define __NR_sysinfo 116 | ||
| 125 | #define __NR_ipc 117 | ||
| 126 | #define __NR_fsync 118 | ||
| 127 | #define __NR_sigreturn 119 | ||
| 128 | #define __NR_clone 120 | ||
| 129 | #define __NR_setdomainname 121 | ||
| 130 | #define __NR_uname 122 | ||
| 131 | #define __NR_modify_ldt 123 | ||
| 132 | #define __NR_adjtimex 124 | ||
| 133 | #define __NR_mprotect 125 | ||
| 134 | #define __NR_sigprocmask 126 | ||
| 135 | #define __NR_create_module 127 | ||
| 136 | #define __NR_init_module 128 | ||
| 137 | #define __NR_delete_module 129 | ||
| 138 | #define __NR_get_kernel_syms 130 | ||
| 139 | #define __NR_quotactl 131 | ||
| 140 | #define __NR_getpgid 132 | ||
| 141 | #define __NR_fchdir 133 | ||
| 142 | #define __NR_bdflush 134 | ||
| 143 | #define __NR_sysfs 135 | ||
| 144 | #define __NR_personality 136 | ||
| 145 | #define __NR_afs_syscall 137 /* Syscall for Andrew File System */ | ||
| 146 | #define __NR_setfsuid 138 | ||
| 147 | #define __NR_setfsgid 139 | ||
| 148 | #define __NR__llseek 140 | ||
| 149 | #define __NR_getdents 141 | ||
| 150 | #define __NR__newselect 142 | ||
| 151 | #define __NR_flock 143 | ||
| 152 | #define __NR_msync 144 | ||
| 153 | #define __NR_readv 145 | ||
| 154 | #define __NR_writev 146 | ||
| 155 | #define __NR_getsid 147 | ||
| 156 | #define __NR_fdatasync 148 | ||
| 157 | #define __NR__sysctl 149 | ||
| 158 | #define __NR_mlock 150 | ||
| 159 | #define __NR_munlock 151 | ||
| 160 | #define __NR_mlockall 152 | ||
| 161 | #define __NR_munlockall 153 | ||
| 162 | #define __NR_sched_setparam 154 | ||
| 163 | #define __NR_sched_getparam 155 | ||
| 164 | #define __NR_sched_setscheduler 156 | ||
| 165 | #define __NR_sched_getscheduler 157 | ||
| 166 | #define __NR_sched_yield 158 | ||
| 167 | #define __NR_sched_get_priority_max 159 | ||
| 168 | #define __NR_sched_get_priority_min 160 | ||
| 169 | #define __NR_sched_rr_get_interval 161 | ||
| 170 | #define __NR_nanosleep 162 | ||
| 171 | #define __NR_mremap 163 | ||
| 172 | #define __NR_setresuid 164 | ||
| 173 | #define __NR_getresuid 165 | ||
| 174 | #define __NR_vm86 166 | ||
| 175 | #define __NR_query_module 167 | ||
| 176 | #define __NR_poll 168 | ||
| 177 | #define __NR_nfsservctl 169 | ||
| 178 | #define __NR_setresgid 170 | ||
| 179 | #define __NR_getresgid 171 | ||
| 180 | #define __NR_prctl 172 | ||
| 181 | #define __NR_rt_sigreturn 173 | ||
| 182 | #define __NR_rt_sigaction 174 | ||
| 183 | #define __NR_rt_sigprocmask 175 | ||
| 184 | #define __NR_rt_sigpending 176 | ||
| 185 | #define __NR_rt_sigtimedwait 177 | ||
| 186 | #define __NR_rt_sigqueueinfo 178 | ||
| 187 | #define __NR_rt_sigsuspend 179 | ||
| 188 | #define __NR_pread64 180 | ||
| 189 | #define __NR_pwrite64 181 | ||
| 190 | #define __NR_chown 182 | ||
| 191 | #define __NR_getcwd 183 | ||
| 192 | #define __NR_capget 184 | ||
| 193 | #define __NR_capset 185 | ||
| 194 | #define __NR_sigaltstack 186 | ||
| 195 | #define __NR_sendfile 187 | ||
| 196 | #define __NR_getpmsg 188 /* some people actually want streams */ | ||
| 197 | #define __NR_putpmsg 189 /* some people actually want streams */ | ||
| 198 | #define __NR_vfork 190 | ||
| 199 | #define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ | ||
| 200 | #define __NR_mmap2 192 | ||
| 201 | #define __NR_truncate64 193 | ||
| 202 | #define __NR_ftruncate64 194 | ||
| 203 | #define __NR_stat64 195 | ||
| 204 | #define __NR_lstat64 196 | ||
| 205 | #define __NR_fstat64 197 | ||
| 206 | #define __NR_lchown32 198 | ||
| 207 | #define __NR_getuid32 199 | ||
| 208 | #define __NR_getgid32 200 | ||
| 209 | #define __NR_geteuid32 201 | ||
| 210 | #define __NR_getegid32 202 | ||
| 211 | #define __NR_setreuid32 203 | ||
| 212 | #define __NR_setregid32 204 | ||
| 213 | #define __NR_getgroups32 205 | ||
| 214 | #define __NR_setgroups32 206 | ||
| 215 | #define __NR_fchown32 207 | ||
| 216 | #define __NR_setresuid32 208 | ||
| 217 | #define __NR_getresuid32 209 | ||
| 218 | #define __NR_setresgid32 210 | ||
| 219 | #define __NR_getresgid32 211 | ||
| 220 | #define __NR_chown32 212 | ||
| 221 | #define __NR_setuid32 213 | ||
| 222 | #define __NR_setgid32 214 | ||
| 223 | #define __NR_setfsuid32 215 | ||
| 224 | #define __NR_setfsgid32 216 | ||
| 225 | #define __NR_pivot_root 217 | ||
| 226 | #define __NR_mincore 218 | ||
| 227 | #define __NR_madvise 219 | ||
| 228 | #define __NR_madvise1 219 /* delete when C lib stub is removed */ | ||
| 229 | #define __NR_getdents64 220 | ||
| 230 | #define __NR_fcntl64 221 | ||
| 231 | /* 223 is unused */ | ||
| 232 | #define __NR_gettid 224 | ||
| 233 | #define __NR_readahead 225 | ||
| 234 | #define __NR_setxattr 226 | ||
| 235 | #define __NR_lsetxattr 227 | ||
| 236 | #define __NR_fsetxattr 228 | ||
| 237 | #define __NR_getxattr 229 | ||
| 238 | #define __NR_lgetxattr 230 | ||
| 239 | #define __NR_fgetxattr 231 | ||
| 240 | #define __NR_listxattr 232 | ||
| 241 | #define __NR_llistxattr 233 | ||
| 242 | #define __NR_flistxattr 234 | ||
| 243 | #define __NR_removexattr 235 | ||
| 244 | #define __NR_lremovexattr 236 | ||
| 245 | #define __NR_fremovexattr 237 | ||
| 246 | #define __NR_tkill 238 | ||
| 247 | #define __NR_sendfile64 239 | ||
| 248 | #define __NR_futex 240 | ||
| 249 | #define __NR_sched_setaffinity 241 | ||
| 250 | #define __NR_sched_getaffinity 242 | ||
| 251 | #define __NR_set_thread_area 243 | ||
| 252 | #define __NR_get_thread_area 244 | ||
| 253 | #define __NR_io_setup 245 | ||
| 254 | #define __NR_io_destroy 246 | ||
| 255 | #define __NR_io_getevents 247 | ||
| 256 | #define __NR_io_submit 248 | ||
| 257 | #define __NR_io_cancel 249 | ||
| 258 | #define __NR_fadvise64 250 | ||
| 259 | /* 251 is available for reuse (was briefly sys_set_zone_reclaim) */ | ||
| 260 | #define __NR_exit_group 252 | ||
| 261 | #define __NR_lookup_dcookie 253 | ||
| 262 | #define __NR_epoll_create 254 | ||
| 263 | #define __NR_epoll_ctl 255 | ||
| 264 | #define __NR_epoll_wait 256 | ||
| 265 | #define __NR_remap_file_pages 257 | ||
| 266 | #define __NR_set_tid_address 258 | ||
| 267 | #define __NR_timer_create 259 | ||
| 268 | #define __NR_timer_settime (__NR_timer_create+1) | ||
| 269 | #define __NR_timer_gettime (__NR_timer_create+2) | ||
| 270 | #define __NR_timer_getoverrun (__NR_timer_create+3) | ||
| 271 | #define __NR_timer_delete (__NR_timer_create+4) | ||
| 272 | #define __NR_clock_settime (__NR_timer_create+5) | ||
| 273 | #define __NR_clock_gettime (__NR_timer_create+6) | ||
| 274 | #define __NR_clock_getres (__NR_timer_create+7) | ||
| 275 | #define __NR_clock_nanosleep (__NR_timer_create+8) | ||
| 276 | #define __NR_statfs64 268 | ||
| 277 | #define __NR_fstatfs64 269 | ||
| 278 | #define __NR_tgkill 270 | ||
| 279 | #define __NR_utimes 271 | ||
| 280 | #define __NR_fadvise64_64 272 | ||
| 281 | #define __NR_vserver 273 | ||
| 282 | #define __NR_mbind 274 | ||
| 283 | #define __NR_get_mempolicy 275 | ||
| 284 | #define __NR_set_mempolicy 276 | ||
| 285 | #define __NR_mq_open 277 | ||
| 286 | #define __NR_mq_unlink (__NR_mq_open+1) | ||
| 287 | #define __NR_mq_timedsend (__NR_mq_open+2) | ||
| 288 | #define __NR_mq_timedreceive (__NR_mq_open+3) | ||
| 289 | #define __NR_mq_notify (__NR_mq_open+4) | ||
| 290 | #define __NR_mq_getsetattr (__NR_mq_open+5) | ||
| 291 | #define __NR_kexec_load 283 | ||
| 292 | #define __NR_waitid 284 | ||
| 293 | /* #define __NR_sys_setaltroot 285 */ | ||
| 294 | #define __NR_add_key 286 | ||
| 295 | #define __NR_request_key 287 | ||
| 296 | #define __NR_keyctl 288 | ||
| 297 | #define __NR_ioprio_set 289 | ||
| 298 | #define __NR_ioprio_get 290 | ||
| 299 | #define __NR_inotify_init 291 | ||
| 300 | #define __NR_inotify_add_watch 292 | ||
| 301 | #define __NR_inotify_rm_watch 293 | ||
| 302 | #define __NR_migrate_pages 294 | ||
| 303 | #define __NR_openat 295 | ||
| 304 | #define __NR_mkdirat 296 | ||
| 305 | #define __NR_mknodat 297 | ||
| 306 | #define __NR_fchownat 298 | ||
| 307 | #define __NR_futimesat 299 | ||
| 308 | #define __NR_fstatat64 300 | ||
| 309 | #define __NR_unlinkat 301 | ||
| 310 | #define __NR_renameat 302 | ||
| 311 | #define __NR_linkat 303 | ||
| 312 | #define __NR_symlinkat 304 | ||
| 313 | #define __NR_readlinkat 305 | ||
| 314 | #define __NR_fchmodat 306 | ||
| 315 | #define __NR_faccessat 307 | ||
| 316 | #define __NR_pselect6 308 | ||
| 317 | #define __NR_ppoll 309 | ||
| 318 | #define __NR_unshare 310 | ||
| 319 | #define __NR_set_robust_list 311 | ||
| 320 | #define __NR_get_robust_list 312 | ||
| 321 | #define __NR_splice 313 | ||
| 322 | #define __NR_sync_file_range 314 | ||
| 323 | #define __NR_tee 315 | ||
| 324 | #define __NR_vmsplice 316 | ||
| 325 | #define __NR_move_pages 317 | ||
| 326 | #define __NR_getcpu 318 | ||
| 327 | #define __NR_epoll_pwait 319 | ||
| 328 | #define __NR_utimensat 320 | ||
| 329 | #define __NR_signalfd 321 | ||
| 330 | #define __NR_timerfd_create 322 | ||
| 331 | #define __NR_eventfd 323 | ||
| 332 | #define __NR_fallocate 324 | ||
| 333 | #define __NR_timerfd_settime 325 | ||
| 334 | #define __NR_timerfd_gettime 326 | ||
| 335 | #define __NR_signalfd4 327 | ||
| 336 | #define __NR_eventfd2 328 | ||
| 337 | #define __NR_epoll_create1 329 | ||
| 338 | #define __NR_dup3 330 | ||
| 339 | #define __NR_pipe2 331 | ||
| 340 | #define __NR_inotify_init1 332 | ||
| 341 | #define __NR_preadv 333 | ||
| 342 | #define __NR_pwritev 334 | ||
| 343 | #define __NR_rt_tgsigqueueinfo 335 | ||
| 344 | #define __NR_perf_event_open 336 | ||
| 345 | #define __NR_recvmmsg 337 | ||
| 346 | #define __NR_fanotify_init 338 | ||
| 347 | #define __NR_fanotify_mark 339 | ||
| 348 | #define __NR_prlimit64 340 | ||
| 349 | #define __NR_name_to_handle_at 341 | ||
| 350 | #define __NR_open_by_handle_at 342 | ||
| 351 | #define __NR_clock_adjtime 343 | ||
| 352 | #define __NR_syncfs 344 | ||
| 353 | #define __NR_sendmmsg 345 | ||
| 354 | #define __NR_setns 346 | ||
| 355 | |||
| 356 | #ifdef __KERNEL__ | ||
| 357 | |||
| 358 | #define NR_syscalls 347 | ||
| 359 | |||
| 360 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
| 361 | #define __ARCH_WANT_OLD_READDIR | ||
| 362 | #define __ARCH_WANT_OLD_STAT | ||
| 363 | #define __ARCH_WANT_STAT64 | ||
| 364 | #define __ARCH_WANT_SYS_ALARM | ||
| 365 | #define __ARCH_WANT_SYS_GETHOSTNAME | ||
| 366 | #define __ARCH_WANT_SYS_IPC | ||
| 367 | #define __ARCH_WANT_SYS_PAUSE | ||
| 368 | #define __ARCH_WANT_SYS_SGETMASK | ||
| 369 | #define __ARCH_WANT_SYS_SIGNAL | ||
| 370 | #define __ARCH_WANT_SYS_TIME | ||
| 371 | #define __ARCH_WANT_SYS_UTIME | ||
| 372 | #define __ARCH_WANT_SYS_WAITPID | ||
| 373 | #define __ARCH_WANT_SYS_SOCKETCALL | ||
| 374 | #define __ARCH_WANT_SYS_FADVISE64 | ||
| 375 | #define __ARCH_WANT_SYS_GETPGRP | ||
| 376 | #define __ARCH_WANT_SYS_LLSEEK | ||
| 377 | #define __ARCH_WANT_SYS_NICE | ||
| 378 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT | ||
| 379 | #define __ARCH_WANT_SYS_OLD_UNAME | ||
| 380 | #define __ARCH_WANT_SYS_OLD_MMAP | ||
| 381 | #define __ARCH_WANT_SYS_OLD_SELECT | ||
| 382 | #define __ARCH_WANT_SYS_OLDUMOUNT | ||
| 383 | #define __ARCH_WANT_SYS_SIGPENDING | ||
| 384 | #define __ARCH_WANT_SYS_SIGPROCMASK | ||
| 385 | #define __ARCH_WANT_SYS_RT_SIGACTION | ||
| 386 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
| 387 | |||
| 388 | /* | ||
| 389 | * "Conditional" syscalls | ||
| 390 | * | ||
| 391 | * What we want is __attribute__((weak,alias("sys_ni_syscall"))), | ||
| 392 | * but it doesn't work on all toolchains, so we just do it by hand | ||
| 393 | */ | ||
| 394 | #ifndef cond_syscall | ||
| 395 | #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") | ||
| 396 | #endif | ||
| 397 | |||
| 398 | #endif /* __KERNEL__ */ | ||
| 399 | #endif /* _ASM_X86_UNISTD_32_H */ | ||
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h new file mode 100644 index 00000000000..20104057344 --- /dev/null +++ b/arch/x86/include/asm/unistd_64.h | |||
| @@ -0,0 +1,729 @@ | |||
| 1 | #ifndef _ASM_X86_UNISTD_64_H | ||
| 2 | #define _ASM_X86_UNISTD_64_H | ||
| 3 | |||
| 4 | #ifndef __SYSCALL | ||
| 5 | #define __SYSCALL(a, b) | ||
| 6 | #endif | ||
| 7 | |||
| 8 | /* | ||
| 9 | * This file contains the system call numbers. | ||
| 10 | * | ||
| 11 | * Note: holes are not allowed. | ||
| 12 | */ | ||
| 13 | |||
| 14 | /* at least 8 syscall per cacheline */ | ||
| 15 | #define __NR_read 0 | ||
| 16 | __SYSCALL(__NR_read, sys_read) | ||
| 17 | #define __NR_write 1 | ||
| 18 | __SYSCALL(__NR_write, sys_write) | ||
| 19 | #define __NR_open 2 | ||
| 20 | __SYSCALL(__NR_open, sys_open) | ||
| 21 | #define __NR_close 3 | ||
| 22 | __SYSCALL(__NR_close, sys_close) | ||
| 23 | #define __NR_stat 4 | ||
| 24 | __SYSCALL(__NR_stat, sys_newstat) | ||
| 25 | #define __NR_fstat 5 | ||
| 26 | __SYSCALL(__NR_fstat, sys_newfstat) | ||
| 27 | #define __NR_lstat 6 | ||
| 28 | __SYSCALL(__NR_lstat, sys_newlstat) | ||
| 29 | #define __NR_poll 7 | ||
| 30 | __SYSCALL(__NR_poll, sys_poll) | ||
| 31 | |||
| 32 | #define __NR_lseek 8 | ||
| 33 | __SYSCALL(__NR_lseek, sys_lseek) | ||
| 34 | #define __NR_mmap 9 | ||
| 35 | __SYSCALL(__NR_mmap, sys_mmap) | ||
| 36 | #define __NR_mprotect 10 | ||
| 37 | __SYSCALL(__NR_mprotect, sys_mprotect) | ||
| 38 | #define __NR_munmap 11 | ||
| 39 | __SYSCALL(__NR_munmap, sys_munmap) | ||
| 40 | #define __NR_brk 12 | ||
| 41 | __SYSCALL(__NR_brk, sys_brk) | ||
| 42 | #define __NR_rt_sigaction 13 | ||
| 43 | __SYSCALL(__NR_rt_sigaction, sys_rt_sigaction) | ||
| 44 | #define __NR_rt_sigprocmask 14 | ||
| 45 | __SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask) | ||
| 46 | #define __NR_rt_sigreturn 15 | ||
| 47 | __SYSCALL(__NR_rt_sigreturn, stub_rt_sigreturn) | ||
| 48 | |||
| 49 | #define __NR_ioctl 16 | ||
| 50 | __SYSCALL(__NR_ioctl, sys_ioctl) | ||
| 51 | #define __NR_pread64 17 | ||
| 52 | __SYSCALL(__NR_pread64, sys_pread64) | ||
| 53 | #define __NR_pwrite64 18 | ||
| 54 | __SYSCALL(__NR_pwrite64, sys_pwrite64) | ||
| 55 | #define __NR_readv 19 | ||
| 56 | __SYSCALL(__NR_readv, sys_readv) | ||
| 57 | #define __NR_writev 20 | ||
| 58 | __SYSCALL(__NR_writev, sys_writev) | ||
| 59 | #define __NR_access 21 | ||
| 60 | __SYSCALL(__NR_access, sys_access) | ||
| 61 | #define __NR_pipe 22 | ||
| 62 | __SYSCALL(__NR_pipe, sys_pipe) | ||
| 63 | #define __NR_select 23 | ||
| 64 | __SYSCALL(__NR_select, sys_select) | ||
| 65 | |||
| 66 | #define __NR_sched_yield 24 | ||
| 67 | __SYSCALL(__NR_sched_yield, sys_sched_yield) | ||
| 68 | #define __NR_mremap 25 | ||
| 69 | __SYSCALL(__NR_mremap, sys_mremap) | ||
| 70 | #define __NR_msync 26 | ||
| 71 | __SYSCALL(__NR_msync, sys_msync) | ||
| 72 | #define __NR_mincore 27 | ||
| 73 | __SYSCALL(__NR_mincore, sys_mincore) | ||
| 74 | #define __NR_madvise 28 | ||
| 75 | __SYSCALL(__NR_madvise, sys_madvise) | ||
| 76 | #define __NR_shmget 29 | ||
| 77 | __SYSCALL(__NR_shmget, sys_shmget) | ||
| 78 | #define __NR_shmat 30 | ||
| 79 | __SYSCALL(__NR_shmat, sys_shmat) | ||
| 80 | #define __NR_shmctl 31 | ||
| 81 | __SYSCALL(__NR_shmctl, sys_shmctl) | ||
| 82 | |||
| 83 | #define __NR_dup 32 | ||
| 84 | __SYSCALL(__NR_dup, sys_dup) | ||
| 85 | #define __NR_dup2 33 | ||
| 86 | __SYSCALL(__NR_dup2, sys_dup2) | ||
| 87 | #define __NR_pause 34 | ||
| 88 | __SYSCALL(__NR_pause, sys_pause) | ||
| 89 | #define __NR_nanosleep 35 | ||
| 90 | __SYSCALL(__NR_nanosleep, sys_nanosleep) | ||
| 91 | #define __NR_getitimer 36 | ||
| 92 | __SYSCALL(__NR_getitimer, sys_getitimer) | ||
| 93 | #define __NR_alarm 37 | ||
| 94 | __SYSCALL(__NR_alarm, sys_alarm) | ||
| 95 | #define __NR_setitimer 38 | ||
| 96 | __SYSCALL(__NR_setitimer, sys_setitimer) | ||
| 97 | #define __NR_getpid 39 | ||
| 98 | __SYSCALL(__NR_getpid, sys_getpid) | ||
| 99 | |||
| 100 | #define __NR_sendfile 40 | ||
| 101 | __SYSCALL(__NR_sendfile, sys_sendfile64) | ||
| 102 | #define __NR_socket 41 | ||
| 103 | __SYSCALL(__NR_socket, sys_socket) | ||
| 104 | #define __NR_connect 42 | ||
| 105 | __SYSCALL(__NR_connect, sys_connect) | ||
| 106 | #define __NR_accept 43 | ||
| 107 | __SYSCALL(__NR_accept, sys_accept) | ||
| 108 | #define __NR_sendto 44 | ||
| 109 | __SYSCALL(__NR_sendto, sys_sendto) | ||
| 110 | #define __NR_recvfrom 45 | ||
| 111 | __SYSCALL(__NR_recvfrom, sys_recvfrom) | ||
| 112 | #define __NR_sendmsg 46 | ||
| 113 | __SYSCALL(__NR_sendmsg, sys_sendmsg) | ||
| 114 | #define __NR_recvmsg 47 | ||
| 115 | __SYSCALL(__NR_recvmsg, sys_recvmsg) | ||
| 116 | |||
| 117 | #define __NR_shutdown 48 | ||
| 118 | __SYSCALL(__NR_shutdown, sys_shutdown) | ||
| 119 | #define __NR_bind 49 | ||
| 120 | __SYSCALL(__NR_bind, sys_bind) | ||
| 121 | #define __NR_listen 50 | ||
| 122 | __SYSCALL(__NR_listen, sys_listen) | ||
| 123 | #define __NR_getsockname 51 | ||
| 124 | __SYSCALL(__NR_getsockname, sys_getsockname) | ||
| 125 | #define __NR_getpeername 52 | ||
| 126 | __SYSCALL(__NR_getpeername, sys_getpeername) | ||
| 127 | #define __NR_socketpair 53 | ||
| 128 | __SYSCALL(__NR_socketpair, sys_socketpair) | ||
| 129 | #define __NR_setsockopt 54 | ||
| 130 | __SYSCALL(__NR_setsockopt, sys_setsockopt) | ||
| 131 | #define __NR_getsockopt 55 | ||
| 132 | __SYSCALL(__NR_getsockopt, sys_getsockopt) | ||
| 133 | |||
| 134 | #define __NR_clone 56 | ||
| 135 | __SYSCALL(__NR_clone, stub_clone) | ||
| 136 | #define __NR_fork 57 | ||
| 137 | __SYSCALL(__NR_fork, stub_fork) | ||
| 138 | #define __NR_vfork 58 | ||
| 139 | __SYSCALL(__NR_vfork, stub_vfork) | ||
| 140 | #define __NR_execve 59 | ||
| 141 | __SYSCALL(__NR_execve, stub_execve) | ||
| 142 | #define __NR_exit 60 | ||
| 143 | __SYSCALL(__NR_exit, sys_exit) | ||
| 144 | #define __NR_wait4 61 | ||
| 145 | __SYSCALL(__NR_wait4, sys_wait4) | ||
| 146 | #define __NR_kill 62 | ||
| 147 | __SYSCALL(__NR_kill, sys_kill) | ||
| 148 | #define __NR_uname 63 | ||
| 149 | __SYSCALL(__NR_uname, sys_newuname) | ||
| 150 | |||
| 151 | #define __NR_semget 64 | ||
| 152 | __SYSCALL(__NR_semget, sys_semget) | ||
| 153 | #define __NR_semop 65 | ||
| 154 | __SYSCALL(__NR_semop, sys_semop) | ||
| 155 | #define __NR_semctl 66 | ||
| 156 | __SYSCALL(__NR_semctl, sys_semctl) | ||
| 157 | #define __NR_shmdt 67 | ||
| 158 | __SYSCALL(__NR_shmdt, sys_shmdt) | ||
| 159 | #define __NR_msgget 68 | ||
| 160 | __SYSCALL(__NR_msgget, sys_msgget) | ||
| 161 | #define __NR_msgsnd 69 | ||
| 162 | __SYSCALL(__NR_msgsnd, sys_msgsnd) | ||
| 163 | #define __NR_msgrcv 70 | ||
| 164 | __SYSCALL(__NR_msgrcv, sys_msgrcv) | ||
| 165 | #define __NR_msgctl 71 | ||
| 166 | __SYSCALL(__NR_msgctl, sys_msgctl) | ||
| 167 | |||
| 168 | #define __NR_fcntl 72 | ||
| 169 | __SYSCALL(__NR_fcntl, sys_fcntl) | ||
| 170 | #define __NR_flock 73 | ||
| 171 | __SYSCALL(__NR_flock, sys_flock) | ||
| 172 | #define __NR_fsync 74 | ||
| 173 | __SYSCALL(__NR_fsync, sys_fsync) | ||
| 174 | #define __NR_fdatasync 75 | ||
| 175 | __SYSCALL(__NR_fdatasync, sys_fdatasync) | ||
| 176 | #define __NR_truncate 76 | ||
| 177 | __SYSCALL(__NR_truncate, sys_truncate) | ||
| 178 | #define __NR_ftruncate 77 | ||
| 179 | __SYSCALL(__NR_ftruncate, sys_ftruncate) | ||
| 180 | #define __NR_getdents 78 | ||
| 181 | __SYSCALL(__NR_getdents, sys_getdents) | ||
| 182 | #define __NR_getcwd 79 | ||
| 183 | __SYSCALL(__NR_getcwd, sys_getcwd) | ||
| 184 | |||
| 185 | #define __NR_chdir 80 | ||
| 186 | __SYSCALL(__NR_chdir, sys_chdir) | ||
| 187 | #define __NR_fchdir 81 | ||
| 188 | __SYSCALL(__NR_fchdir, sys_fchdir) | ||
| 189 | #define __NR_rename 82 | ||
| 190 | __SYSCALL(__NR_rename, sys_rename) | ||
| 191 | #define __NR_mkdir 83 | ||
| 192 | __SYSCALL(__NR_mkdir, sys_mkdir) | ||
| 193 | #define __NR_rmdir 84 | ||
| 194 | __SYSCALL(__NR_rmdir, sys_rmdir) | ||
| 195 | #define __NR_creat 85 | ||
| 196 | __SYSCALL(__NR_creat, sys_creat) | ||
| 197 | #define __NR_link 86 | ||
| 198 | __SYSCALL(__NR_link, sys_link) | ||
| 199 | #define __NR_unlink 87 | ||
| 200 | __SYSCALL(__NR_unlink, sys_unlink) | ||
| 201 | |||
| 202 | #define __NR_symlink 88 | ||
| 203 | __SYSCALL(__NR_symlink, sys_symlink) | ||
| 204 | #define __NR_readlink 89 | ||
| 205 | __SYSCALL(__NR_readlink, sys_readlink) | ||
| 206 | #define __NR_chmod 90 | ||
| 207 | __SYSCALL(__NR_chmod, sys_chmod) | ||
| 208 | #define __NR_fchmod 91 | ||
| 209 | __SYSCALL(__NR_fchmod, sys_fchmod) | ||
| 210 | #define __NR_chown 92 | ||
| 211 | __SYSCALL(__NR_chown, sys_chown) | ||
| 212 | #define __NR_fchown 93 | ||
| 213 | __SYSCALL(__NR_fchown, sys_fchown) | ||
| 214 | #define __NR_lchown 94 | ||
| 215 | __SYSCALL(__NR_lchown, sys_lchown) | ||
| 216 | #define __NR_umask 95 | ||
| 217 | __SYSCALL(__NR_umask, sys_umask) | ||
| 218 | |||
| 219 | #define __NR_gettimeofday 96 | ||
| 220 | __SYSCALL(__NR_gettimeofday, sys_gettimeofday) | ||
| 221 | #define __NR_getrlimit 97 | ||
| 222 | __SYSCALL(__NR_getrlimit, sys_getrlimit) | ||
| 223 | #define __NR_getrusage 98 | ||
| 224 | __SYSCALL(__NR_getrusage, sys_getrusage) | ||
| 225 | #define __NR_sysinfo 99 | ||
| 226 | __SYSCALL(__NR_sysinfo, sys_sysinfo) | ||
| 227 | #define __NR_times 100 | ||
| 228 | __SYSCALL(__NR_times, sys_times) | ||
| 229 | #define __NR_ptrace 101 | ||
| 230 | __SYSCALL(__NR_ptrace, sys_ptrace) | ||
| 231 | #define __NR_getuid 102 | ||
| 232 | __SYSCALL(__NR_getuid, sys_getuid) | ||
| 233 | #define __NR_syslog 103 | ||
| 234 | __SYSCALL(__NR_syslog, sys_syslog) | ||
| 235 | |||
| 236 | /* at the very end the stuff that never runs during the benchmarks */ | ||
| 237 | #define __NR_getgid 104 | ||
| 238 | __SYSCALL(__NR_getgid, sys_getgid) | ||
| 239 | #define __NR_setuid 105 | ||
| 240 | __SYSCALL(__NR_setuid, sys_setuid) | ||
| 241 | #define __NR_setgid 106 | ||
| 242 | __SYSCALL(__NR_setgid, sys_setgid) | ||
| 243 | #define __NR_geteuid 107 | ||
| 244 | __SYSCALL(__NR_geteuid, sys_geteuid) | ||
| 245 | #define __NR_getegid 108 | ||
| 246 | __SYSCALL(__NR_getegid, sys_getegid) | ||
| 247 | #define __NR_setpgid 109 | ||
| 248 | __SYSCALL(__NR_setpgid, sys_setpgid) | ||
| 249 | #define __NR_getppid 110 | ||
| 250 | __SYSCALL(__NR_getppid, sys_getppid) | ||
| 251 | #define __NR_getpgrp 111 | ||
| 252 | __SYSCALL(__NR_getpgrp, sys_getpgrp) | ||
| 253 | |||
| 254 | #define __NR_setsid 112 | ||
| 255 | __SYSCALL(__NR_setsid, sys_setsid) | ||
| 256 | #define __NR_setreuid 113 | ||
| 257 | __SYSCALL(__NR_setreuid, sys_setreuid) | ||
| 258 | #define __NR_setregid 114 | ||
| 259 | __SYSCALL(__NR_setregid, sys_setregid) | ||
| 260 | #define __NR_getgroups 115 | ||
| 261 | __SYSCALL(__NR_getgroups, sys_getgroups) | ||
| 262 | #define __NR_setgroups 116 | ||
| 263 | __SYSCALL(__NR_setgroups, sys_setgroups) | ||
| 264 | #define __NR_setresuid 117 | ||
| 265 | __SYSCALL(__NR_setresuid, sys_setresuid) | ||
| 266 | #define __NR_getresuid 118 | ||
| 267 | __SYSCALL(__NR_getresuid, sys_getresuid) | ||
| 268 | #define __NR_setresgid 119 | ||
| 269 | __SYSCALL(__NR_setresgid, sys_setresgid) | ||
| 270 | |||
| 271 | #define __NR_getresgid 120 | ||
| 272 | __SYSCALL(__NR_getresgid, sys_getresgid) | ||
| 273 | #define __NR_getpgid 121 | ||
| 274 | __SYSCALL(__NR_getpgid, sys_getpgid) | ||
| 275 | #define __NR_setfsuid 122 | ||
| 276 | __SYSCALL(__NR_setfsuid, sys_setfsuid) | ||
| 277 | #define __NR_setfsgid 123 | ||
| 278 | __SYSCALL(__NR_setfsgid, sys_setfsgid) | ||
| 279 | #define __NR_getsid 124 | ||
| 280 | __SYSCALL(__NR_getsid, sys_getsid) | ||
| 281 | #define __NR_capget 125 | ||
| 282 | __SYSCALL(__NR_capget, sys_capget) | ||
| 283 | #define __NR_capset 126 | ||
| 284 | __SYSCALL(__NR_capset, sys_capset) | ||
| 285 | |||
| 286 | #define __NR_rt_sigpending 127 | ||
| 287 | __SYSCALL(__NR_rt_sigpending, sys_rt_sigpending) | ||
| 288 | #define __NR_rt_sigtimedwait 128 | ||
| 289 | __SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait) | ||
| 290 | #define __NR_rt_sigqueueinfo 129 | ||
| 291 | __SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo) | ||
| 292 | #define __NR_rt_sigsuspend 130 | ||
| 293 | __SYSCALL(__NR_rt_sigsuspend, sys_rt_sigsuspend) | ||
| 294 | #define __NR_sigaltstack 131 | ||
| 295 | __SYSCALL(__NR_sigaltstack, stub_sigaltstack) | ||
| 296 | #define __NR_utime 132 | ||
| 297 | __SYSCALL(__NR_utime, sys_utime) | ||
| 298 | #define __NR_mknod 133 | ||
| 299 | __SYSCALL(__NR_mknod, sys_mknod) | ||
| 300 | |||
| 301 | /* Only needed for a.out */ | ||
| 302 | #define __NR_uselib 134 | ||
| 303 | __SYSCALL(__NR_uselib, sys_ni_syscall) | ||
| 304 | #define __NR_personality 135 | ||
| 305 | __SYSCALL(__NR_personality, sys_personality) | ||
| 306 | |||
| 307 | #define __NR_ustat 136 | ||
| 308 | __SYSCALL(__NR_ustat, sys_ustat) | ||
| 309 | #define __NR_statfs 137 | ||
| 310 | __SYSCALL(__NR_statfs, sys_statfs) | ||
| 311 | #define __NR_fstatfs 138 | ||
| 312 | __SYSCALL(__NR_fstatfs, sys_fstatfs) | ||
| 313 | #define __NR_sysfs 139 | ||
| 314 | __SYSCALL(__NR_sysfs, sys_sysfs) | ||
| 315 | |||
| 316 | #define __NR_getpriority 140 | ||
| 317 | __SYSCALL(__NR_getpriority, sys_getpriority) | ||
| 318 | #define __NR_setpriority 141 | ||
| 319 | __SYSCALL(__NR_setpriority, sys_setpriority) | ||
| 320 | #define __NR_sched_setparam 142 | ||
| 321 | __SYSCALL(__NR_sched_setparam, sys_sched_setparam) | ||
| 322 | #define __NR_sched_getparam 143 | ||
| 323 | __SYSCALL(__NR_sched_getparam, sys_sched_getparam) | ||
| 324 | #define __NR_sched_setscheduler 144 | ||
| 325 | __SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler) | ||
| 326 | #define __NR_sched_getscheduler 145 | ||
| 327 | __SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler) | ||
| 328 | #define __NR_sched_get_priority_max 146 | ||
| 329 | __SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max) | ||
| 330 | #define __NR_sched_get_priority_min 147 | ||
| 331 | __SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min) | ||
| 332 | #define __NR_sched_rr_get_interval 148 | ||
| 333 | __SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval) | ||
| 334 | |||
| 335 | #define __NR_mlock 149 | ||
| 336 | __SYSCALL(__NR_mlock, sys_mlock) | ||
| 337 | #define __NR_munlock 150 | ||
| 338 | __SYSCALL(__NR_munlock, sys_munlock) | ||
| 339 | #define __NR_mlockall 151 | ||
| 340 | __SYSCALL(__NR_mlockall, sys_mlockall) | ||
| 341 | #define __NR_munlockall 152 | ||
| 342 | __SYSCALL(__NR_munlockall, sys_munlockall) | ||
| 343 | |||
| 344 | #define __NR_vhangup 153 | ||
| 345 | __SYSCALL(__NR_vhangup, sys_vhangup) | ||
| 346 | |||
| 347 | #define __NR_modify_ldt 154 | ||
| 348 | __SYSCALL(__NR_modify_ldt, sys_modify_ldt) | ||
| 349 | |||
| 350 | #define __NR_pivot_root 155 | ||
| 351 | __SYSCALL(__NR_pivot_root, sys_pivot_root) | ||
| 352 | |||
| 353 | #define __NR__sysctl 156 | ||
| 354 | __SYSCALL(__NR__sysctl, sys_sysctl) | ||
| 355 | |||
| 356 | #define __NR_prctl 157 | ||
| 357 | __SYSCALL(__NR_prctl, sys_prctl) | ||
| 358 | #define __NR_arch_prctl 158 | ||
| 359 | __SYSCALL(__NR_arch_prctl, sys_arch_prctl) | ||
| 360 | |||
| 361 | #define __NR_adjtimex 159 | ||
| 362 | __SYSCALL(__NR_adjtimex, sys_adjtimex) | ||
| 363 | |||
| 364 | #define __NR_setrlimit 160 | ||
| 365 | __SYSCALL(__NR_setrlimit, sys_setrlimit) | ||
| 366 | |||
| 367 | #define __NR_chroot 161 | ||
| 368 | __SYSCALL(__NR_chroot, sys_chroot) | ||
| 369 | |||
| 370 | #define __NR_sync 162 | ||
| 371 | __SYSCALL(__NR_sync, sys_sync) | ||
| 372 | |||
| 373 | #define __NR_acct 163 | ||
| 374 | __SYSCALL(__NR_acct, sys_acct) | ||
| 375 | |||
| 376 | #define __NR_settimeofday 164 | ||
| 377 | __SYSCALL(__NR_settimeofday, sys_settimeofday) | ||
| 378 | |||
| 379 | #define __NR_mount 165 | ||
| 380 | __SYSCALL(__NR_mount, sys_mount) | ||
| 381 | #define __NR_umount2 166 | ||
| 382 | __SYSCALL(__NR_umount2, sys_umount) | ||
| 383 | |||
| 384 | #define __NR_swapon 167 | ||
| 385 | __SYSCALL(__NR_swapon, sys_swapon) | ||
| 386 | #define __NR_swapoff 168 | ||
| 387 | __SYSCALL(__NR_swapoff, sys_swapoff) | ||
| 388 | |||
| 389 | #define __NR_reboot 169 | ||
| 390 | __SYSCALL(__NR_reboot, sys_reboot) | ||
| 391 | |||
| 392 | #define __NR_sethostname 170 | ||
| 393 | __SYSCALL(__NR_sethostname, sys_sethostname) | ||
| 394 | #define __NR_setdomainname 171 | ||
| 395 | __SYSCALL(__NR_setdomainname, sys_setdomainname) | ||
| 396 | |||
| 397 | #define __NR_iopl 172 | ||
| 398 | __SYSCALL(__NR_iopl, stub_iopl) | ||
| 399 | #define __NR_ioperm 173 | ||
| 400 | __SYSCALL(__NR_ioperm, sys_ioperm) | ||
| 401 | |||
| 402 | #define __NR_create_module 174 | ||
| 403 | __SYSCALL(__NR_create_module, sys_ni_syscall) | ||
| 404 | #define __NR_init_module 175 | ||
| 405 | __SYSCALL(__NR_init_module, sys_init_module) | ||
| 406 | #define __NR_delete_module 176 | ||
| 407 | __SYSCALL(__NR_delete_module, sys_delete_module) | ||
| 408 | #define __NR_get_kernel_syms 177 | ||
| 409 | __SYSCALL(__NR_get_kernel_syms, sys_ni_syscall) | ||
| 410 | #define __NR_query_module 178 | ||
| 411 | __SYSCALL(__NR_query_module, sys_ni_syscall) | ||
| 412 | |||
| 413 | #define __NR_quotactl 179 | ||
| 414 | __SYSCALL(__NR_quotactl, sys_quotactl) | ||
| 415 | |||
| 416 | #define __NR_nfsservctl 180 | ||
| 417 | __SYSCALL(__NR_nfsservctl, sys_ni_syscall) | ||
| 418 | |||
| 419 | /* reserved for LiS/STREAMS */ | ||
| 420 | #define __NR_getpmsg 181 | ||
| 421 | __SYSCALL(__NR_getpmsg, sys_ni_syscall) | ||
| 422 | #define __NR_putpmsg 182 | ||
| 423 | __SYSCALL(__NR_putpmsg, sys_ni_syscall) | ||
| 424 | |||
| 425 | /* reserved for AFS */ | ||
| 426 | #define __NR_afs_syscall 183 | ||
| 427 | __SYSCALL(__NR_afs_syscall, sys_ni_syscall) | ||
| 428 | |||
| 429 | /* reserved for tux */ | ||
| 430 | #define __NR_tuxcall 184 | ||
| 431 | __SYSCALL(__NR_tuxcall, sys_ni_syscall) | ||
| 432 | |||
| 433 | #define __NR_security 185 | ||
| 434 | __SYSCALL(__NR_security, sys_ni_syscall) | ||
| 435 | |||
| 436 | #define __NR_gettid 186 | ||
| 437 | __SYSCALL(__NR_gettid, sys_gettid) | ||
| 438 | |||
| 439 | #define __NR_readahead 187 | ||
| 440 | __SYSCALL(__NR_readahead, sys_readahead) | ||
| 441 | #define __NR_setxattr 188 | ||
| 442 | __SYSCALL(__NR_setxattr, sys_setxattr) | ||
| 443 | #define __NR_lsetxattr 189 | ||
| 444 | __SYSCALL(__NR_lsetxattr, sys_lsetxattr) | ||
| 445 | #define __NR_fsetxattr 190 | ||
| 446 | __SYSCALL(__NR_fsetxattr, sys_fsetxattr) | ||
| 447 | #define __NR_getxattr 191 | ||
| 448 | __SYSCALL(__NR_getxattr, sys_getxattr) | ||
| 449 | #define __NR_lgetxattr 192 | ||
| 450 | __SYSCALL(__NR_lgetxattr, sys_lgetxattr) | ||
| 451 | #define __NR_fgetxattr 193 | ||
| 452 | __SYSCALL(__NR_fgetxattr, sys_fgetxattr) | ||
| 453 | #define __NR_listxattr 194 | ||
| 454 | __SYSCALL(__NR_listxattr, sys_listxattr) | ||
| 455 | #define __NR_llistxattr 195 | ||
| 456 | __SYSCALL(__NR_llistxattr, sys_llistxattr) | ||
| 457 | #define __NR_flistxattr 196 | ||
| 458 | __SYSCALL(__NR_flistxattr, sys_flistxattr) | ||
| 459 | #define __NR_removexattr 197 | ||
| 460 | __SYSCALL(__NR_removexattr, sys_removexattr) | ||
| 461 | #define __NR_lremovexattr 198 | ||
| 462 | __SYSCALL(__NR_lremovexattr, sys_lremovexattr) | ||
| 463 | #define __NR_fremovexattr 199 | ||
| 464 | __SYSCALL(__NR_fremovexattr, sys_fremovexattr) | ||
| 465 | #define __NR_tkill 200 | ||
| 466 | __SYSCALL(__NR_tkill, sys_tkill) | ||
| 467 | #define __NR_time 201 | ||
| 468 | __SYSCALL(__NR_time, sys_time) | ||
| 469 | #define __NR_futex 202 | ||
| 470 | __SYSCALL(__NR_futex, sys_futex) | ||
| 471 | #define __NR_sched_setaffinity 203 | ||
| 472 | __SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity) | ||
| 473 | #define __NR_sched_getaffinity 204 | ||
| 474 | __SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity) | ||
| 475 | #define __NR_set_thread_area 205 | ||
| 476 | __SYSCALL(__NR_set_thread_area, sys_ni_syscall) /* use arch_prctl */ | ||
| 477 | #define __NR_io_setup 206 | ||
| 478 | __SYSCALL(__NR_io_setup, sys_io_setup) | ||
| 479 | #define __NR_io_destroy 207 | ||
| 480 | __SYSCALL(__NR_io_destroy, sys_io_destroy) | ||
| 481 | #define __NR_io_getevents 208 | ||
| 482 | __SYSCALL(__NR_io_getevents, sys_io_getevents) | ||
| 483 | #define __NR_io_submit 209 | ||
| 484 | __SYSCALL(__NR_io_submit, sys_io_submit) | ||
| 485 | #define __NR_io_cancel 210 | ||
| 486 | __SYSCALL(__NR_io_cancel, sys_io_cancel) | ||
| 487 | #define __NR_get_thread_area 211 | ||
| 488 | __SYSCALL(__NR_get_thread_area, sys_ni_syscall) /* use arch_prctl */ | ||
| 489 | #define __NR_lookup_dcookie 212 | ||
| 490 | __SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie) | ||
| 491 | #define __NR_epoll_create 213 | ||
| 492 | __SYSCALL(__NR_epoll_create, sys_epoll_create) | ||
| 493 | #define __NR_epoll_ctl_old 214 | ||
| 494 | __SYSCALL(__NR_epoll_ctl_old, sys_ni_syscall) | ||
| 495 | #define __NR_epoll_wait_old 215 | ||
| 496 | __SYSCALL(__NR_epoll_wait_old, sys_ni_syscall) | ||
| 497 | #define __NR_remap_file_pages 216 | ||
| 498 | __SYSCALL(__NR_remap_file_pages, sys_remap_file_pages) | ||
| 499 | #define __NR_getdents64 217 | ||
| 500 | __SYSCALL(__NR_getdents64, sys_getdents64) | ||
| 501 | #define __NR_set_tid_address 218 | ||
| 502 | __SYSCALL(__NR_set_tid_address, sys_set_tid_address) | ||
| 503 | #define __NR_restart_syscall 219 | ||
| 504 | __SYSCALL(__NR_restart_syscall, sys_restart_syscall) | ||
| 505 | #define __NR_semtimedop 220 | ||
| 506 | __SYSCALL(__NR_semtimedop, sys_semtimedop) | ||
| 507 | #define __NR_fadvise64 221 | ||
| 508 | __SYSCALL(__NR_fadvise64, sys_fadvise64) | ||
| 509 | #define __NR_timer_create 222 | ||
| 510 | __SYSCALL(__NR_timer_create, sys_timer_create) | ||
| 511 | #define __NR_timer_settime 223 | ||
| 512 | __SYSCALL(__NR_timer_settime, sys_timer_settime) | ||
| 513 | #define __NR_timer_gettime 224 | ||
| 514 | __SYSCALL(__NR_timer_gettime, sys_timer_gettime) | ||
| 515 | #define __NR_timer_getoverrun 225 | ||
| 516 | __SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun) | ||
| 517 | #define __NR_timer_delete 226 | ||
| 518 | __SYSCALL(__NR_timer_delete, sys_timer_delete) | ||
| 519 | #define __NR_clock_settime 227 | ||
| 520 | __SYSCALL(__NR_clock_settime, sys_clock_settime) | ||
| 521 | #define __NR_clock_gettime 228 | ||
| 522 | __SYSCALL(__NR_clock_gettime, sys_clock_gettime) | ||
| 523 | #define __NR_clock_getres 229 | ||
| 524 | __SYSCALL(__NR_clock_getres, sys_clock_getres) | ||
| 525 | #define __NR_clock_nanosleep 230 | ||
| 526 | __SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep) | ||
| 527 | #define __NR_exit_group 231 | ||
| 528 | __SYSCALL(__NR_exit_group, sys_exit_group) | ||
| 529 | #define __NR_epoll_wait 232 | ||
| 530 | __SYSCALL(__NR_epoll_wait, sys_epoll_wait) | ||
| 531 | #define __NR_epoll_ctl 233 | ||
| 532 | __SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) | ||
| 533 | #define __NR_tgkill 234 | ||
| 534 | __SYSCALL(__NR_tgkill, sys_tgkill) | ||
| 535 | #define __NR_utimes 235 | ||
| 536 | __SYSCALL(__NR_utimes, sys_utimes) | ||
| 537 | #define __NR_vserver 236 | ||
| 538 | __SYSCALL(__NR_vserver, sys_ni_syscall) | ||
| 539 | #define __NR_mbind 237 | ||
| 540 | __SYSCALL(__NR_mbind, sys_mbind) | ||
| 541 | #define __NR_set_mempolicy 238 | ||
| 542 | __SYSCALL(__NR_set_mempolicy, sys_set_mempolicy) | ||
| 543 | #define __NR_get_mempolicy 239 | ||
| 544 | __SYSCALL(__NR_get_mempolicy, sys_get_mempolicy) | ||
| 545 | #define __NR_mq_open 240 | ||
| 546 | __SYSCALL(__NR_mq_open, sys_mq_open) | ||
| 547 | #define __NR_mq_unlink 241 | ||
| 548 | __SYSCALL(__NR_mq_unlink, sys_mq_unlink) | ||
| 549 | #define __NR_mq_timedsend 242 | ||
| 550 | __SYSCALL(__NR_mq_timedsend, sys_mq_timedsend) | ||
| 551 | #define __NR_mq_timedreceive 243 | ||
| 552 | __SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive) | ||
| 553 | #define __NR_mq_notify 244 | ||
| 554 | __SYSCALL(__NR_mq_notify, sys_mq_notify) | ||
| 555 | #define __NR_mq_getsetattr 245 | ||
| 556 | __SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) | ||
| 557 | #define __NR_kexec_load 246 | ||
| 558 | __SYSCALL(__NR_kexec_load, sys_kexec_load) | ||
| 559 | #define __NR_waitid 247 | ||
| 560 | __SYSCALL(__NR_waitid, sys_waitid) | ||
| 561 | #define __NR_add_key 248 | ||
| 562 | __SYSCALL(__NR_add_key, sys_add_key) | ||
| 563 | #define __NR_request_key 249 | ||
| 564 | __SYSCALL(__NR_request_key, sys_request_key) | ||
| 565 | #define __NR_keyctl 250 | ||
| 566 | __SYSCALL(__NR_keyctl, sys_keyctl) | ||
| 567 | #define __NR_ioprio_set 251 | ||
| 568 | __SYSCALL(__NR_ioprio_set, sys_ioprio_set) | ||
| 569 | #define __NR_ioprio_get 252 | ||
| 570 | __SYSCALL(__NR_ioprio_get, sys_ioprio_get) | ||
| 571 | #define __NR_inotify_init 253 | ||
| 572 | __SYSCALL(__NR_inotify_init, sys_inotify_init) | ||
| 573 | #define __NR_inotify_add_watch 254 | ||
| 574 | __SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch) | ||
| 575 | #define __NR_inotify_rm_watch 255 | ||
| 576 | __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch) | ||
| 577 | #define __NR_migrate_pages 256 | ||
| 578 | __SYSCALL(__NR_migrate_pages, sys_migrate_pages) | ||
| 579 | #define __NR_openat 257 | ||
| 580 | __SYSCALL(__NR_openat, sys_openat) | ||
| 581 | #define __NR_mkdirat 258 | ||
| 582 | __SYSCALL(__NR_mkdirat, sys_mkdirat) | ||
| 583 | #define __NR_mknodat 259 | ||
| 584 | __SYSCALL(__NR_mknodat, sys_mknodat) | ||
| 585 | #define __NR_fchownat 260 | ||
| 586 | __SYSCALL(__NR_fchownat, sys_fchownat) | ||
| 587 | #define __NR_futimesat 261 | ||
| 588 | __SYSCALL(__NR_futimesat, sys_futimesat) | ||
| 589 | #define __NR_newfstatat 262 | ||
| 590 | __SYSCALL(__NR_newfstatat, sys_newfstatat) | ||
| 591 | #define __NR_unlinkat 263 | ||
| 592 | __SYSCALL(__NR_unlinkat, sys_unlinkat) | ||
| 593 | #define __NR_renameat 264 | ||
| 594 | __SYSCALL(__NR_renameat, sys_renameat) | ||
| 595 | #define __NR_linkat 265 | ||
| 596 | __SYSCALL(__NR_linkat, sys_linkat) | ||
| 597 | #define __NR_symlinkat 266 | ||
| 598 | __SYSCALL(__NR_symlinkat, sys_symlinkat) | ||
| 599 | #define __NR_readlinkat 267 | ||
| 600 | __SYSCALL(__NR_readlinkat, sys_readlinkat) | ||
| 601 | #define __NR_fchmodat 268 | ||
| 602 | __SYSCALL(__NR_fchmodat, sys_fchmodat) | ||
| 603 | #define __NR_faccessat 269 | ||
| 604 | __SYSCALL(__NR_faccessat, sys_faccessat) | ||
| 605 | #define __NR_pselect6 270 | ||
| 606 | __SYSCALL(__NR_pselect6, sys_pselect6) | ||
| 607 | #define __NR_ppoll 271 | ||
| 608 | __SYSCALL(__NR_ppoll, sys_ppoll) | ||
| 609 | #define __NR_unshare 272 | ||
| 610 | __SYSCALL(__NR_unshare, sys_unshare) | ||
| 611 | #define __NR_set_robust_list 273 | ||
| 612 | __SYSCALL(__NR_set_robust_list, sys_set_robust_list) | ||
| 613 | #define __NR_get_robust_list 274 | ||
| 614 | __SYSCALL(__NR_get_robust_list, sys_get_robust_list) | ||
| 615 | #define __NR_splice 275 | ||
| 616 | __SYSCALL(__NR_splice, sys_splice) | ||
| 617 | #define __NR_tee 276 | ||
| 618 | __SYSCALL(__NR_tee, sys_tee) | ||
| 619 | #define __NR_sync_file_range 277 | ||
| 620 | __SYSCALL(__NR_sync_file_range, sys_sync_file_range) | ||
| 621 | #define __NR_vmsplice 278 | ||
| 622 | __SYSCALL(__NR_vmsplice, sys_vmsplice) | ||
| 623 | #define __NR_move_pages 279 | ||
| 624 | __SYSCALL(__NR_move_pages, sys_move_pages) | ||
| 625 | #define __NR_utimensat 280 | ||
| 626 | __SYSCALL(__NR_utimensat, sys_utimensat) | ||
| 627 | #define __IGNORE_getcpu /* implemented as a vsyscall */ | ||
| 628 | #define __NR_epoll_pwait 281 | ||
| 629 | __SYSCALL(__NR_epoll_pwait, sys_epoll_pwait) | ||
| 630 | #define __NR_signalfd 282 | ||
| 631 | __SYSCALL(__NR_signalfd, sys_signalfd) | ||
| 632 | #define __NR_timerfd_create 283 | ||
| 633 | __SYSCALL(__NR_timerfd_create, sys_timerfd_create) | ||
| 634 | #define __NR_eventfd 284 | ||
| 635 | __SYSCALL(__NR_eventfd, sys_eventfd) | ||
| 636 | #define __NR_fallocate 285 | ||
| 637 | __SYSCALL(__NR_fallocate, sys_fallocate) | ||
| 638 | #define __NR_timerfd_settime 286 | ||
| 639 | __SYSCALL(__NR_timerfd_settime, sys_timerfd_settime) | ||
| 640 | #define __NR_timerfd_gettime 287 | ||
| 641 | __SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime) | ||
| 642 | #define __NR_accept4 288 | ||
| 643 | __SYSCALL(__NR_accept4, sys_accept4) | ||
| 644 | #define __NR_signalfd4 289 | ||
| 645 | __SYSCALL(__NR_signalfd4, sys_signalfd4) | ||
| 646 | #define __NR_eventfd2 290 | ||
| 647 | __SYSCALL(__NR_eventfd2, sys_eventfd2) | ||
| 648 | #define __NR_epoll_create1 291 | ||
| 649 | __SYSCALL(__NR_epoll_create1, sys_epoll_create1) | ||
| 650 | #define __NR_dup3 292 | ||
| 651 | __SYSCALL(__NR_dup3, sys_dup3) | ||
| 652 | #define __NR_pipe2 293 | ||
| 653 | __SYSCALL(__NR_pipe2, sys_pipe2) | ||
| 654 | #define __NR_inotify_init1 294 | ||
| 655 | __SYSCALL(__NR_inotify_init1, sys_inotify_init1) | ||
| 656 | #define __NR_preadv 295 | ||
| 657 | __SYSCALL(__NR_preadv, sys_preadv) | ||
| 658 | #define __NR_pwritev 296 | ||
| 659 | __SYSCALL(__NR_pwritev, sys_pwritev) | ||
| 660 | #define __NR_rt_tgsigqueueinfo 297 | ||
| 661 | __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) | ||
| 662 | #define __NR_perf_event_open 298 | ||
| 663 | __SYSCALL(__NR_perf_event_open, sys_perf_event_open) | ||
| 664 | #define __NR_recvmmsg 299 | ||
| 665 | __SYSCALL(__NR_recvmmsg, sys_recvmmsg) | ||
| 666 | #define __NR_fanotify_init 300 | ||
| 667 | __SYSCALL(__NR_fanotify_init, sys_fanotify_init) | ||
| 668 | #define __NR_fanotify_mark 301 | ||
| 669 | __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark) | ||
| 670 | #define __NR_prlimit64 302 | ||
| 671 | __SYSCALL(__NR_prlimit64, sys_prlimit64) | ||
| 672 | #define __NR_name_to_handle_at 303 | ||
| 673 | __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) | ||
| 674 | #define __NR_open_by_handle_at 304 | ||
| 675 | __SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at) | ||
| 676 | #define __NR_clock_adjtime 305 | ||
| 677 | __SYSCALL(__NR_clock_adjtime, sys_clock_adjtime) | ||
| 678 | #define __NR_syncfs 306 | ||
| 679 | __SYSCALL(__NR_syncfs, sys_syncfs) | ||
| 680 | #define __NR_sendmmsg 307 | ||
| 681 | __SYSCALL(__NR_sendmmsg, sys_sendmmsg) | ||
| 682 | #define __NR_setns 308 | ||
| 683 | __SYSCALL(__NR_setns, sys_setns) | ||
| 684 | #define __NR_getcpu 309 | ||
| 685 | __SYSCALL(__NR_getcpu, sys_getcpu) | ||
| 686 | |||
| 687 | #ifndef __NO_STUBS | ||
| 688 | #define __ARCH_WANT_OLD_READDIR | ||
| 689 | #define __ARCH_WANT_OLD_STAT | ||
| 690 | #define __ARCH_WANT_SYS_ALARM | ||
| 691 | #define __ARCH_WANT_SYS_GETHOSTNAME | ||
| 692 | #define __ARCH_WANT_SYS_PAUSE | ||
| 693 | #define __ARCH_WANT_SYS_SGETMASK | ||
| 694 | #define __ARCH_WANT_SYS_SIGNAL | ||
| 695 | #define __ARCH_WANT_SYS_UTIME | ||
| 696 | #define __ARCH_WANT_SYS_WAITPID | ||
| 697 | #define __ARCH_WANT_SYS_SOCKETCALL | ||
| 698 | #define __ARCH_WANT_SYS_FADVISE64 | ||
| 699 | #define __ARCH_WANT_SYS_GETPGRP | ||
| 700 | #define __ARCH_WANT_SYS_LLSEEK | ||
| 701 | #define __ARCH_WANT_SYS_NICE | ||
| 702 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT | ||
| 703 | #define __ARCH_WANT_SYS_OLD_UNAME | ||
| 704 | #define __ARCH_WANT_SYS_OLDUMOUNT | ||
| 705 | #define __ARCH_WANT_SYS_SIGPENDING | ||
| 706 | #define __ARCH_WANT_SYS_SIGPROCMASK | ||
| 707 | #define __ARCH_WANT_SYS_RT_SIGACTION | ||
| 708 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
| 709 | #define __ARCH_WANT_SYS_TIME | ||
| 710 | #define __ARCH_WANT_COMPAT_SYS_TIME | ||
| 711 | #endif /* __NO_STUBS */ | ||
| 712 | |||
| 713 | #ifdef __KERNEL__ | ||
| 714 | |||
| 715 | #ifndef COMPILE_OFFSETS | ||
| 716 | #include <asm/asm-offsets.h> | ||
| 717 | #define NR_syscalls (__NR_syscall_max + 1) | ||
| 718 | #endif | ||
| 719 | |||
| 720 | /* | ||
| 721 | * "Conditional" syscalls | ||
| 722 | * | ||
| 723 | * What we want is __attribute__((weak,alias("sys_ni_syscall"))), | ||
| 724 | * but it doesn't work on all toolchains, so we just do it by hand | ||
| 725 | */ | ||
| 726 | #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") | ||
| 727 | #endif /* __KERNEL__ */ | ||
| 728 | |||
| 729 | #endif /* _ASM_X86_UNISTD_64_H */ | ||
diff --git a/arch/x86/include/asm/xen/grant_table.h b/arch/x86/include/asm/xen/grant_table.h new file mode 100644 index 00000000000..fdbbb45767a --- /dev/null +++ b/arch/x86/include/asm/xen/grant_table.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef _ASM_X86_XEN_GRANT_TABLE_H | ||
| 2 | #define _ASM_X86_XEN_GRANT_TABLE_H | ||
| 3 | |||
| 4 | #define xen_alloc_vm_area(size) alloc_vm_area(size) | ||
| 5 | #define xen_free_vm_area(area) free_vm_area(area) | ||
| 6 | |||
| 7 | #endif /* _ASM_X86_XEN_GRANT_TABLE_H */ | ||
diff --git a/arch/x86/kernel/acpi/realmode/Makefile b/arch/x86/kernel/acpi/realmode/Makefile new file mode 100644 index 00000000000..6a564ac67ef --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/Makefile | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | # | ||
| 2 | # arch/x86/kernel/acpi/realmode/Makefile | ||
| 3 | # | ||
| 4 | # This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | # License. See the file "COPYING" in the main directory of this archive | ||
| 6 | # for more details. | ||
| 7 | # | ||
| 8 | |||
| 9 | always := wakeup.bin | ||
| 10 | targets := wakeup.elf wakeup.lds | ||
| 11 | |||
| 12 | wakeup-y += wakeup.o wakemain.o video-mode.o copy.o bioscall.o regs.o | ||
| 13 | |||
| 14 | # The link order of the video-*.o modules can matter. In particular, | ||
| 15 | # video-vga.o *must* be listed first, followed by video-vesa.o. | ||
| 16 | # Hardware-specific drivers should follow in the order they should be | ||
| 17 | # probed, and video-bios.o should typically be last. | ||
| 18 | wakeup-y += video-vga.o | ||
| 19 | wakeup-y += video-vesa.o | ||
| 20 | wakeup-y += video-bios.o | ||
| 21 | |||
| 22 | targets += $(wakeup-y) | ||
| 23 | |||
| 24 | bootsrc := $(src)/../../../boot | ||
| 25 | |||
| 26 | # --------------------------------------------------------------------------- | ||
| 27 | |||
| 28 | # How to compile the 16-bit code. Note we always compile for -march=i386, | ||
| 29 | # that way we can complain to the user if the CPU is insufficient. | ||
| 30 | # Compile with _SETUP since this is similar to the boot-time setup code. | ||
| 31 | KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D_WAKEUP -D__KERNEL__ \ | ||
| 32 | -I$(srctree)/$(bootsrc) \ | ||
| 33 | $(cflags-y) \ | ||
| 34 | -Wall -Wstrict-prototypes \ | ||
| 35 | -march=i386 -mregparm=3 \ | ||
| 36 | -include $(srctree)/$(bootsrc)/code16gcc.h \ | ||
| 37 | -fno-strict-aliasing -fomit-frame-pointer \ | ||
| 38 | $(call cc-option, -ffreestanding) \ | ||
| 39 | $(call cc-option, -fno-toplevel-reorder,\ | ||
| 40 | $(call cc-option, -fno-unit-at-a-time)) \ | ||
| 41 | $(call cc-option, -fno-stack-protector) \ | ||
| 42 | $(call cc-option, -mpreferred-stack-boundary=2) | ||
| 43 | KBUILD_CFLAGS += $(call cc-option, -m32) | ||
| 44 | KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ | ||
| 45 | GCOV_PROFILE := n | ||
| 46 | |||
| 47 | WAKEUP_OBJS = $(addprefix $(obj)/,$(wakeup-y)) | ||
| 48 | |||
| 49 | LDFLAGS_wakeup.elf := -T | ||
| 50 | |||
| 51 | CPPFLAGS_wakeup.lds += -P -C | ||
| 52 | |||
| 53 | $(obj)/wakeup.elf: $(obj)/wakeup.lds $(WAKEUP_OBJS) FORCE | ||
| 54 | $(call if_changed,ld) | ||
| 55 | |||
| 56 | OBJCOPYFLAGS_wakeup.bin := -O binary | ||
| 57 | |||
| 58 | $(obj)/wakeup.bin: $(obj)/wakeup.elf FORCE | ||
| 59 | $(call if_changed,objcopy) | ||
diff --git a/arch/x86/kernel/acpi/realmode/bioscall.S b/arch/x86/kernel/acpi/realmode/bioscall.S new file mode 100644 index 00000000000..f51eb0bb56c --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/bioscall.S | |||
| @@ -0,0 +1 @@ | |||
| #include "../../../boot/bioscall.S" | |||
diff --git a/arch/x86/kernel/acpi/realmode/copy.S b/arch/x86/kernel/acpi/realmode/copy.S new file mode 100644 index 00000000000..dc59ebee69d --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/copy.S | |||
| @@ -0,0 +1 @@ | |||
| #include "../../../boot/copy.S" | |||
diff --git a/arch/x86/kernel/acpi/realmode/regs.c b/arch/x86/kernel/acpi/realmode/regs.c new file mode 100644 index 00000000000..6206033ba20 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/regs.c | |||
| @@ -0,0 +1 @@ | |||
| #include "../../../boot/regs.c" | |||
diff --git a/arch/x86/kernel/acpi/realmode/video-bios.c b/arch/x86/kernel/acpi/realmode/video-bios.c new file mode 100644 index 00000000000..7deabc144a2 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/video-bios.c | |||
| @@ -0,0 +1 @@ | |||
| #include "../../../boot/video-bios.c" | |||
diff --git a/arch/x86/kernel/acpi/realmode/video-mode.c b/arch/x86/kernel/acpi/realmode/video-mode.c new file mode 100644 index 00000000000..328ad209f11 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/video-mode.c | |||
| @@ -0,0 +1 @@ | |||
| #include "../../../boot/video-mode.c" | |||
diff --git a/arch/x86/kernel/acpi/realmode/video-vesa.c b/arch/x86/kernel/acpi/realmode/video-vesa.c new file mode 100644 index 00000000000..9dbb9672226 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/video-vesa.c | |||
| @@ -0,0 +1 @@ | |||
| #include "../../../boot/video-vesa.c" | |||
diff --git a/arch/x86/kernel/acpi/realmode/video-vga.c b/arch/x86/kernel/acpi/realmode/video-vga.c new file mode 100644 index 00000000000..bcc81255f37 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/video-vga.c | |||
| @@ -0,0 +1 @@ | |||
| #include "../../../boot/video-vga.c" | |||
diff --git a/arch/x86/kernel/acpi/realmode/wakemain.c b/arch/x86/kernel/acpi/realmode/wakemain.c new file mode 100644 index 00000000000..883962d9eef --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/wakemain.c | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | #include "wakeup.h" | ||
| 2 | #include "boot.h" | ||
| 3 | |||
| 4 | static void udelay(int loops) | ||
| 5 | { | ||
| 6 | while (loops--) | ||
| 7 | io_delay(); /* Approximately 1 us */ | ||
| 8 | } | ||
| 9 | |||
| 10 | static void beep(unsigned int hz) | ||
| 11 | { | ||
| 12 | u8 enable; | ||
| 13 | |||
| 14 | if (!hz) { | ||
| 15 | enable = 0x00; /* Turn off speaker */ | ||
| 16 | } else { | ||
| 17 | u16 div = 1193181/hz; | ||
| 18 | |||
| 19 | outb(0xb6, 0x43); /* Ctr 2, squarewave, load, binary */ | ||
| 20 | io_delay(); | ||
| 21 | outb(div, 0x42); /* LSB of counter */ | ||
| 22 | io_delay(); | ||
| 23 | outb(div >> 8, 0x42); /* MSB of counter */ | ||
| 24 | io_delay(); | ||
| 25 | |||
| 26 | enable = 0x03; /* Turn on speaker */ | ||
| 27 | } | ||
| 28 | inb(0x61); /* Dummy read of System Control Port B */ | ||
| 29 | io_delay(); | ||
| 30 | outb(enable, 0x61); /* Enable timer 2 output to speaker */ | ||
| 31 | io_delay(); | ||
| 32 | } | ||
| 33 | |||
| 34 | #define DOT_HZ 880 | ||
| 35 | #define DASH_HZ 587 | ||
| 36 | #define US_PER_DOT 125000 | ||
| 37 | |||
| 38 | /* Okay, this is totally silly, but it's kind of fun. */ | ||
| 39 | static void send_morse(const char *pattern) | ||
| 40 | { | ||
| 41 | char s; | ||
| 42 | |||
| 43 | while ((s = *pattern++)) { | ||
| 44 | switch (s) { | ||
| 45 | case '.': | ||
| 46 | beep(DOT_HZ); | ||
| 47 | udelay(US_PER_DOT); | ||
| 48 | beep(0); | ||
| 49 | udelay(US_PER_DOT); | ||
| 50 | break; | ||
| 51 | case '-': | ||
| 52 | beep(DASH_HZ); | ||
| 53 | udelay(US_PER_DOT * 3); | ||
| 54 | beep(0); | ||
| 55 | udelay(US_PER_DOT); | ||
| 56 | break; | ||
| 57 | default: /* Assume it's a space */ | ||
| 58 | udelay(US_PER_DOT * 3); | ||
| 59 | break; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | void main(void) | ||
| 65 | { | ||
| 66 | /* Kill machine if structures are wrong */ | ||
| 67 | if (wakeup_header.real_magic != 0x12345678) | ||
| 68 | while (1); | ||
| 69 | |||
| 70 | if (wakeup_header.realmode_flags & 4) | ||
| 71 | send_morse("...-"); | ||
| 72 | |||
| 73 | if (wakeup_header.realmode_flags & 1) | ||
| 74 | asm volatile("lcallw $0xc000,$3"); | ||
| 75 | |||
| 76 | if (wakeup_header.realmode_flags & 2) { | ||
| 77 | /* Need to call BIOS */ | ||
| 78 | probe_cards(0); | ||
| 79 | set_mode(wakeup_header.video_mode); | ||
| 80 | } | ||
| 81 | } | ||
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S new file mode 100644 index 00000000000..b4fd836e405 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/wakeup.S | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* | ||
| 2 | * ACPI wakeup real mode startup stub | ||
| 3 | */ | ||
| 4 | #include <asm/segment.h> | ||
| 5 | #include <asm/msr-index.h> | ||
| 6 | #include <asm/page_types.h> | ||
| 7 | #include <asm/pgtable_types.h> | ||
| 8 | #include <asm/processor-flags.h> | ||
| 9 | #include "wakeup.h" | ||
| 10 | |||
| 11 | .code16 | ||
| 12 | .section ".jump", "ax" | ||
| 13 | .globl _start | ||
| 14 | _start: | ||
| 15 | cli | ||
| 16 | jmp wakeup_code | ||
| 17 | |||
| 18 | /* This should match the structure in wakeup.h */ | ||
| 19 | .section ".header", "a" | ||
| 20 | .globl wakeup_header | ||
| 21 | wakeup_header: | ||
| 22 | video_mode: .short 0 /* Video mode number */ | ||
| 23 | pmode_return: .byte 0x66, 0xea /* ljmpl */ | ||
| 24 | .long 0 /* offset goes here */ | ||
| 25 | .short __KERNEL_CS | ||
| 26 | pmode_cr0: .long 0 /* Saved %cr0 */ | ||
| 27 | pmode_cr3: .long 0 /* Saved %cr3 */ | ||
| 28 | pmode_cr4: .long 0 /* Saved %cr4 */ | ||
| 29 | pmode_efer: .quad 0 /* Saved EFER */ | ||
| 30 | pmode_gdt: .quad 0 | ||
| 31 | pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */ | ||
| 32 | pmode_behavior: .long 0 /* Wakeup behavior flags */ | ||
| 33 | realmode_flags: .long 0 | ||
| 34 | real_magic: .long 0 | ||
| 35 | trampoline_segment: .word 0 | ||
| 36 | _pad1: .byte 0 | ||
| 37 | wakeup_jmp: .byte 0xea /* ljmpw */ | ||
| 38 | wakeup_jmp_off: .word 3f | ||
| 39 | wakeup_jmp_seg: .word 0 | ||
| 40 | wakeup_gdt: .quad 0, 0, 0 | ||
| 41 | signature: .long WAKEUP_HEADER_SIGNATURE | ||
| 42 | |||
| 43 | .text | ||
| 44 | .code16 | ||
| 45 | wakeup_code: | ||
| 46 | cld | ||
| 47 | |||
| 48 | /* Apparently some dimwit BIOS programmers don't know how to | ||
| 49 | program a PM to RM transition, and we might end up here with | ||
| 50 | junk in the data segment descriptor registers. The only way | ||
| 51 | to repair that is to go into PM and fix it ourselves... */ | ||
| 52 | movw $16, %cx | ||
| 53 | lgdtl %cs:wakeup_gdt | ||
| 54 | movl %cr0, %eax | ||
| 55 | orb $X86_CR0_PE, %al | ||
| 56 | movl %eax, %cr0 | ||
| 57 | jmp 1f | ||
| 58 | 1: ljmpw $8, $2f | ||
| 59 | 2: | ||
| 60 | movw %cx, %ds | ||
| 61 | movw %cx, %es | ||
| 62 | movw %cx, %ss | ||
| 63 | movw %cx, %fs | ||
| 64 | movw %cx, %gs | ||
| 65 | |||
| 66 | andb $~X86_CR0_PE, %al | ||
| 67 | movl %eax, %cr0 | ||
| 68 | jmp wakeup_jmp | ||
| 69 | 3: | ||
| 70 | /* Set up segments */ | ||
| 71 | movw %cs, %ax | ||
| 72 | movw %ax, %ds | ||
| 73 | movw %ax, %es | ||
| 74 | movw %ax, %ss | ||
| 75 | lidtl wakeup_idt | ||
| 76 | |||
| 77 | movl $wakeup_stack_end, %esp | ||
| 78 | |||
| 79 | /* Clear the EFLAGS */ | ||
| 80 | pushl $0 | ||
| 81 | popfl | ||
| 82 | |||
| 83 | /* Check header signature... */ | ||
| 84 | movl signature, %eax | ||
| 85 | cmpl $WAKEUP_HEADER_SIGNATURE, %eax | ||
| 86 | jne bogus_real_magic | ||
| 87 | |||
| 88 | /* Check we really have everything... */ | ||
| 89 | movl end_signature, %eax | ||
| 90 | cmpl $WAKEUP_END_SIGNATURE, %eax | ||
| 91 | jne bogus_real_magic | ||
| 92 | |||
| 93 | /* Call the C code */ | ||
| 94 | calll main | ||
| 95 | |||
| 96 | /* Restore MISC_ENABLE before entering protected mode, in case | ||
| 97 | BIOS decided to clear XD_DISABLE during S3. */ | ||
| 98 | movl pmode_behavior, %eax | ||
| 99 | btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax | ||
| 100 | jnc 1f | ||
| 101 | |||
| 102 | movl pmode_misc_en, %eax | ||
| 103 | movl pmode_misc_en + 4, %edx | ||
| 104 | movl $MSR_IA32_MISC_ENABLE, %ecx | ||
| 105 | wrmsr | ||
| 106 | 1: | ||
| 107 | |||
| 108 | /* Do any other stuff... */ | ||
| 109 | |||
| 110 | #ifndef CONFIG_64BIT | ||
| 111 | /* This could also be done in C code... */ | ||
| 112 | movl pmode_cr3, %eax | ||
| 113 | movl %eax, %cr3 | ||
| 114 | |||
| 115 | movl pmode_cr4, %ecx | ||
| 116 | jecxz 1f | ||
| 117 | movl %ecx, %cr4 | ||
| 118 | 1: | ||
| 119 | movl pmode_efer, %eax | ||
| 120 | movl pmode_efer + 4, %edx | ||
| 121 | movl %eax, %ecx | ||
| 122 | orl %edx, %ecx | ||
| 123 | jz 1f | ||
| 124 | movl $MSR_EFER, %ecx | ||
| 125 | wrmsr | ||
| 126 | 1: | ||
| 127 | |||
| 128 | lgdtl pmode_gdt | ||
| 129 | |||
| 130 | /* This really couldn't... */ | ||
| 131 | movl pmode_cr0, %eax | ||
| 132 | movl %eax, %cr0 | ||
| 133 | jmp pmode_return | ||
| 134 | #else | ||
| 135 | pushw $0 | ||
| 136 | pushw trampoline_segment | ||
| 137 | pushw $0 | ||
| 138 | lret | ||
| 139 | #endif | ||
| 140 | |||
| 141 | bogus_real_magic: | ||
| 142 | 1: | ||
| 143 | hlt | ||
| 144 | jmp 1b | ||
| 145 | |||
| 146 | .data | ||
| 147 | .balign 8 | ||
| 148 | |||
| 149 | /* This is the standard real-mode IDT */ | ||
| 150 | wakeup_idt: | ||
| 151 | .word 0xffff /* limit */ | ||
| 152 | .long 0 /* address */ | ||
| 153 | .word 0 | ||
| 154 | |||
| 155 | .globl HEAP, heap_end | ||
| 156 | HEAP: | ||
| 157 | .long wakeup_heap | ||
| 158 | heap_end: | ||
| 159 | .long wakeup_stack | ||
| 160 | |||
| 161 | .bss | ||
| 162 | wakeup_heap: | ||
| 163 | .space 2048 | ||
| 164 | wakeup_stack: | ||
| 165 | .space 2048 | ||
| 166 | wakeup_stack_end: | ||
| 167 | |||
| 168 | .section ".signature","a" | ||
| 169 | end_signature: | ||
| 170 | .long WAKEUP_END_SIGNATURE | ||
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/kernel/acpi/realmode/wakeup.h new file mode 100644 index 00000000000..97a29e1430e --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/wakeup.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* | ||
| 2 | * Definitions for the wakeup data structure at the head of the | ||
| 3 | * wakeup code. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H | ||
| 7 | #define ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H | ||
| 8 | |||
| 9 | #ifndef __ASSEMBLY__ | ||
| 10 | #include <linux/types.h> | ||
| 11 | |||
| 12 | /* This must match data at wakeup.S */ | ||
| 13 | struct wakeup_header { | ||
| 14 | u16 video_mode; /* Video mode number */ | ||
| 15 | u16 _jmp1; /* ljmpl opcode, 32-bit only */ | ||
| 16 | u32 pmode_entry; /* Protected mode resume point, 32-bit only */ | ||
| 17 | u16 _jmp2; /* CS value, 32-bit only */ | ||
| 18 | u32 pmode_cr0; /* Protected mode cr0 */ | ||
| 19 | u32 pmode_cr3; /* Protected mode cr3 */ | ||
| 20 | u32 pmode_cr4; /* Protected mode cr4 */ | ||
| 21 | u32 pmode_efer_low; /* Protected mode EFER */ | ||
| 22 | u32 pmode_efer_high; | ||
| 23 | u64 pmode_gdt; | ||
| 24 | u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */ | ||
| 25 | u32 pmode_misc_en_high; | ||
| 26 | u32 pmode_behavior; /* Wakeup routine behavior flags */ | ||
| 27 | u32 realmode_flags; | ||
| 28 | u32 real_magic; | ||
| 29 | u16 trampoline_segment; /* segment with trampoline code, 64-bit only */ | ||
| 30 | u8 _pad1; | ||
| 31 | u8 wakeup_jmp; | ||
| 32 | u16 wakeup_jmp_off; | ||
| 33 | u16 wakeup_jmp_seg; | ||
| 34 | u64 wakeup_gdt[3]; | ||
| 35 | u32 signature; /* To check we have correct structure */ | ||
| 36 | } __attribute__((__packed__)); | ||
| 37 | |||
| 38 | extern struct wakeup_header wakeup_header; | ||
| 39 | #endif | ||
| 40 | |||
| 41 | #define WAKEUP_HEADER_OFFSET 8 | ||
| 42 | #define WAKEUP_HEADER_SIGNATURE 0x51ee1111 | ||
| 43 | #define WAKEUP_END_SIGNATURE 0x65a22c82 | ||
| 44 | |||
| 45 | /* Wakeup behavior bits */ | ||
| 46 | #define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 | ||
| 47 | |||
| 48 | #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ | ||
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S new file mode 100644 index 00000000000..d4f8010a5b1 --- /dev/null +++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /* | ||
| 2 | * wakeup.ld | ||
| 3 | * | ||
| 4 | * Linker script for the real-mode wakeup code | ||
| 5 | */ | ||
| 6 | #undef i386 | ||
| 7 | #include "wakeup.h" | ||
| 8 | |||
| 9 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") | ||
| 10 | OUTPUT_ARCH(i386) | ||
| 11 | ENTRY(_start) | ||
| 12 | |||
| 13 | SECTIONS | ||
| 14 | { | ||
| 15 | . = 0; | ||
| 16 | .jump : { | ||
| 17 | *(.jump) | ||
| 18 | } = 0x90909090 | ||
| 19 | |||
| 20 | . = WAKEUP_HEADER_OFFSET; | ||
| 21 | .header : { | ||
| 22 | *(.header) | ||
| 23 | } | ||
| 24 | |||
| 25 | . = ALIGN(16); | ||
| 26 | .text : { | ||
| 27 | *(.text*) | ||
| 28 | } = 0x90909090 | ||
| 29 | |||
| 30 | . = ALIGN(16); | ||
| 31 | .rodata : { | ||
| 32 | *(.rodata*) | ||
| 33 | } | ||
| 34 | |||
| 35 | .videocards : { | ||
| 36 | video_cards = .; | ||
| 37 | *(.videocards) | ||
| 38 | video_cards_end = .; | ||
| 39 | } | ||
| 40 | |||
| 41 | . = ALIGN(16); | ||
| 42 | .data : { | ||
| 43 | *(.data*) | ||
| 44 | } | ||
| 45 | |||
| 46 | . = ALIGN(16); | ||
| 47 | .bss : { | ||
| 48 | __bss_start = .; | ||
| 49 | *(.bss) | ||
| 50 | __bss_end = .; | ||
| 51 | } | ||
| 52 | |||
| 53 | .signature : { | ||
| 54 | *(.signature) | ||
| 55 | } | ||
| 56 | |||
| 57 | _end = .; | ||
| 58 | |||
| 59 | /DISCARD/ : { | ||
| 60 | *(.note*) | ||
| 61 | } | ||
| 62 | } | ||
diff --git a/arch/x86/kernel/acpi/wakeup_rm.S b/arch/x86/kernel/acpi/wakeup_rm.S new file mode 100644 index 00000000000..63b8ab524f2 --- /dev/null +++ b/arch/x86/kernel/acpi/wakeup_rm.S | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | /* | ||
| 2 | * Wrapper script for the realmode binary as a transport object | ||
| 3 | * before copying to low memory. | ||
| 4 | */ | ||
| 5 | #include <asm/page_types.h> | ||
| 6 | |||
| 7 | .section ".x86_trampoline","a" | ||
| 8 | .balign PAGE_SIZE | ||
| 9 | .globl acpi_wakeup_code | ||
| 10 | acpi_wakeup_code: | ||
| 11 | .incbin "arch/x86/kernel/acpi/realmode/wakeup.bin" | ||
| 12 | .size acpi_wakeup_code, .-acpi_wakeup_code | ||
diff --git a/arch/x86/kernel/cpu/sched.c b/arch/x86/kernel/cpu/sched.c new file mode 100644 index 00000000000..a640ae5ad20 --- /dev/null +++ b/arch/x86/kernel/cpu/sched.c | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | #include <linux/sched.h> | ||
| 2 | #include <linux/math64.h> | ||
| 3 | #include <linux/percpu.h> | ||
| 4 | #include <linux/irqflags.h> | ||
| 5 | |||
| 6 | #include <asm/cpufeature.h> | ||
| 7 | #include <asm/processor.h> | ||
| 8 | |||
| 9 | #ifdef CONFIG_SMP | ||
| 10 | |||
| 11 | static DEFINE_PER_CPU(struct aperfmperf, old_perf_sched); | ||
| 12 | |||
| 13 | static unsigned long scale_aperfmperf(void) | ||
| 14 | { | ||
| 15 | struct aperfmperf val, *old = &__get_cpu_var(old_perf_sched); | ||
| 16 | unsigned long ratio, flags; | ||
| 17 | |||
| 18 | local_irq_save(flags); | ||
| 19 | get_aperfmperf(&val); | ||
| 20 | local_irq_restore(flags); | ||
| 21 | |||
| 22 | ratio = calc_aperfmperf_ratio(old, &val); | ||
| 23 | *old = val; | ||
| 24 | |||
| 25 | return ratio; | ||
| 26 | } | ||
| 27 | |||
| 28 | unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu) | ||
| 29 | { | ||
| 30 | /* | ||
| 31 | * do aperf/mperf on the cpu level because it includes things | ||
| 32 | * like turbo mode, which are relevant to full cores. | ||
| 33 | */ | ||
| 34 | if (boot_cpu_has(X86_FEATURE_APERFMPERF)) | ||
| 35 | return scale_aperfmperf(); | ||
| 36 | |||
| 37 | /* | ||
| 38 | * maybe have something cpufreq here | ||
| 39 | */ | ||
| 40 | |||
| 41 | return default_scale_freq_power(sd, cpu); | ||
| 42 | } | ||
| 43 | |||
| 44 | unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu) | ||
| 45 | { | ||
| 46 | /* | ||
| 47 | * aperf/mperf already includes the smt gain | ||
| 48 | */ | ||
| 49 | if (boot_cpu_has(X86_FEATURE_APERFMPERF)) | ||
| 50 | return SCHED_LOAD_SCALE; | ||
| 51 | |||
| 52 | return default_scale_smt_power(sd, cpu); | ||
| 53 | } | ||
| 54 | |||
| 55 | #endif | ||
diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c new file mode 100644 index 00000000000..43e9ccf4494 --- /dev/null +++ b/arch/x86/kernel/init_task.c | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | #include <linux/mm.h> | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/sched.h> | ||
| 4 | #include <linux/init.h> | ||
| 5 | #include <linux/init_task.h> | ||
| 6 | #include <linux/fs.h> | ||
| 7 | #include <linux/mqueue.h> | ||
| 8 | |||
| 9 | #include <asm/uaccess.h> | ||
| 10 | #include <asm/pgtable.h> | ||
| 11 | #include <asm/desc.h> | ||
| 12 | |||
| 13 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | ||
| 14 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Initial thread structure. | ||
| 18 | * | ||
| 19 | * We need to make sure that this is THREAD_SIZE aligned due to the | ||
| 20 | * way process stacks are handled. This is done by having a special | ||
| 21 | * "init_task" linker map entry.. | ||
| 22 | */ | ||
| 23 | union thread_union init_thread_union __init_task_data = | ||
| 24 | { INIT_THREAD_INFO(init_task) }; | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Initial task structure. | ||
| 28 | * | ||
| 29 | * All other task structs will be allocated on slabs in fork.c | ||
| 30 | */ | ||
| 31 | struct task_struct init_task = INIT_TASK(init_task); | ||
| 32 | EXPORT_SYMBOL(init_task); | ||
| 33 | |||
| 34 | /* | ||
| 35 | * per-CPU TSS segments. Threads are completely 'soft' on Linux, | ||
| 36 | * no more per-task TSS's. The TSS size is kept cacheline-aligned | ||
| 37 | * so they are allowed to end up in the .data..cacheline_aligned | ||
| 38 | * section. Since TSS's are completely CPU-local, we want them | ||
| 39 | * on exact cacheline boundaries, to eliminate cacheline ping-pong. | ||
| 40 | */ | ||
| 41 | DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; | ||
| 42 | |||
diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c new file mode 100644 index 00000000000..177183cbb6a --- /dev/null +++ b/arch/x86/kernel/mca_32.c | |||
| @@ -0,0 +1,477 @@ | |||
| 1 | /* | ||
| 2 | * Written by Martin Kolinek, February 1996 | ||
| 3 | * | ||
| 4 | * Changes: | ||
| 5 | * | ||
| 6 | * Chris Beauregard July 28th, 1996 | ||
| 7 | * - Fixed up integrated SCSI detection | ||
| 8 | * | ||
| 9 | * Chris Beauregard August 3rd, 1996 | ||
| 10 | * - Made mca_info local | ||
| 11 | * - Made integrated registers accessible through standard function calls | ||
| 12 | * - Added name field | ||
| 13 | * - More sanity checking | ||
| 14 | * | ||
| 15 | * Chris Beauregard August 9th, 1996 | ||
| 16 | * - Rewrote /proc/mca | ||
| 17 | * | ||
| 18 | * Chris Beauregard January 7th, 1997 | ||
| 19 | * - Added basic NMI-processing | ||
| 20 | * - Added more information to mca_info structure | ||
| 21 | * | ||
| 22 | * David Weinehall October 12th, 1998 | ||
| 23 | * - Made a lot of cleaning up in the source | ||
| 24 | * - Added use of save_flags / restore_flags | ||
| 25 | * - Added the 'driver_loaded' flag in MCA_adapter | ||
| 26 | * - Added an alternative implemention of ZP Gu's mca_find_unused_adapter | ||
| 27 | * | ||
| 28 | * David Weinehall March 24th, 1999 | ||
| 29 | * - Fixed the output of 'Driver Installed' in /proc/mca/pos | ||
| 30 | * - Made the Integrated Video & SCSI show up even if they have id 0000 | ||
| 31 | * | ||
| 32 | * Alexander Viro November 9th, 1999 | ||
| 33 | * - Switched to regular procfs methods | ||
| 34 | * | ||
| 35 | * Alfred Arnold & David Weinehall August 23rd, 2000 | ||
| 36 | * - Added support for Planar POS-registers | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include <linux/module.h> | ||
| 40 | #include <linux/types.h> | ||
| 41 | #include <linux/errno.h> | ||
| 42 | #include <linux/kernel.h> | ||
| 43 | #include <linux/mca.h> | ||
| 44 | #include <linux/kprobes.h> | ||
| 45 | #include <linux/slab.h> | ||
| 46 | #include <asm/system.h> | ||
| 47 | #include <asm/io.h> | ||
| 48 | #include <linux/proc_fs.h> | ||
| 49 | #include <linux/mman.h> | ||
| 50 | #include <linux/mm.h> | ||
| 51 | #include <linux/pagemap.h> | ||
| 52 | #include <linux/ioport.h> | ||
| 53 | #include <asm/uaccess.h> | ||
| 54 | #include <linux/init.h> | ||
| 55 | |||
| 56 | static unsigned char which_scsi; | ||
| 57 | |||
| 58 | int MCA_bus; | ||
| 59 | EXPORT_SYMBOL(MCA_bus); | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Motherboard register spinlock. Untested on SMP at the moment, but | ||
| 63 | * are there any MCA SMP boxes? | ||
| 64 | * | ||
| 65 | * Yes - Alan | ||
| 66 | */ | ||
| 67 | static DEFINE_SPINLOCK(mca_lock); | ||
| 68 | |||
| 69 | /* Build the status info for the adapter */ | ||
| 70 | |||
| 71 | static void mca_configure_adapter_status(struct mca_device *mca_dev) | ||
| 72 | { | ||
| 73 | mca_dev->status = MCA_ADAPTER_NONE; | ||
| 74 | |||
| 75 | mca_dev->pos_id = mca_dev->pos[0] | ||
| 76 | + (mca_dev->pos[1] << 8); | ||
| 77 | |||
| 78 | if (!mca_dev->pos_id && mca_dev->slot < MCA_MAX_SLOT_NR) { | ||
| 79 | |||
| 80 | /* | ||
| 81 | * id = 0x0000 usually indicates hardware failure, | ||
| 82 | * however, ZP Gu (zpg@castle.net> reports that his 9556 | ||
| 83 | * has 0x0000 as id and everything still works. There | ||
| 84 | * also seem to be an adapter with id = 0x0000; the | ||
| 85 | * NCR Parallel Bus Memory Card. Until this is confirmed, | ||
| 86 | * however, this code will stay. | ||
| 87 | */ | ||
| 88 | |||
| 89 | mca_dev->status = MCA_ADAPTER_ERROR; | ||
| 90 | |||
| 91 | return; | ||
| 92 | } else if (mca_dev->pos_id != 0xffff) { | ||
| 93 | |||
| 94 | /* | ||
| 95 | * 0xffff usually indicates that there's no adapter, | ||
| 96 | * however, some integrated adapters may have 0xffff as | ||
| 97 | * their id and still be valid. Examples are on-board | ||
| 98 | * VGA of the 55sx, the integrated SCSI of the 56 & 57, | ||
| 99 | * and possibly also the 95 ULTIMEDIA. | ||
| 100 | */ | ||
| 101 | |||
| 102 | mca_dev->status = MCA_ADAPTER_NORMAL; | ||
| 103 | } | ||
| 104 | |||
| 105 | if ((mca_dev->pos_id == 0xffff || | ||
| 106 | mca_dev->pos_id == 0x0000) && mca_dev->slot >= MCA_MAX_SLOT_NR) { | ||
| 107 | int j; | ||
| 108 | |||
| 109 | for (j = 2; j < 8; j++) { | ||
| 110 | if (mca_dev->pos[j] != 0xff) { | ||
| 111 | mca_dev->status = MCA_ADAPTER_NORMAL; | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | if (!(mca_dev->pos[2] & MCA_ENABLED)) { | ||
| 118 | |||
| 119 | /* enabled bit is in POS 2 */ | ||
| 120 | |||
| 121 | mca_dev->status = MCA_ADAPTER_DISABLED; | ||
| 122 | } | ||
| 123 | } /* mca_configure_adapter_status */ | ||
| 124 | |||
| 125 | /*--------------------------------------------------------------------*/ | ||
| 126 | |||
| 127 | static struct resource mca_standard_resources[] = { | ||
| 128 | { .start = 0x60, .end = 0x60, .name = "system control port B (MCA)" }, | ||
| 129 | { .start = 0x90, .end = 0x90, .name = "arbitration (MCA)" }, | ||
| 130 | { .start = 0x91, .end = 0x91, .name = "card Select Feedback (MCA)" }, | ||
| 131 | { .start = 0x92, .end = 0x92, .name = "system Control port A (MCA)" }, | ||
| 132 | { .start = 0x94, .end = 0x94, .name = "system board setup (MCA)" }, | ||
| 133 | { .start = 0x96, .end = 0x97, .name = "POS (MCA)" }, | ||
| 134 | { .start = 0x100, .end = 0x107, .name = "POS (MCA)" } | ||
| 135 | }; | ||
| 136 | |||
| 137 | #define MCA_STANDARD_RESOURCES ARRAY_SIZE(mca_standard_resources) | ||
| 138 | |||
| 139 | /* | ||
| 140 | * mca_read_and_store_pos - read the POS registers into a memory buffer | ||
| 141 | * @pos: a char pointer to 8 bytes, contains the POS register value on | ||
| 142 | * successful return | ||
| 143 | * | ||
| 144 | * Returns 1 if a card actually exists (i.e. the pos isn't | ||
| 145 | * all 0xff) or 0 otherwise | ||
| 146 | */ | ||
| 147 | static int mca_read_and_store_pos(unsigned char *pos) | ||
| 148 | { | ||
| 149 | int j; | ||
| 150 | int found = 0; | ||
| 151 | |||
| 152 | for (j = 0; j < 8; j++) { | ||
| 153 | pos[j] = inb_p(MCA_POS_REG(j)); | ||
| 154 | if (pos[j] != 0xff) { | ||
| 155 | /* 0xff all across means no device. 0x00 means | ||
| 156 | * something's broken, but a device is | ||
| 157 | * probably there. However, if you get 0x00 | ||
| 158 | * from a motherboard register it won't matter | ||
| 159 | * what we find. For the record, on the | ||
| 160 | * 57SLC, the integrated SCSI adapter has | ||
| 161 | * 0xffff for the adapter ID, but nonzero for | ||
| 162 | * other registers. */ | ||
| 163 | |||
| 164 | found = 1; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | return found; | ||
| 168 | } | ||
| 169 | |||
| 170 | static unsigned char mca_pc_read_pos(struct mca_device *mca_dev, int reg) | ||
| 171 | { | ||
| 172 | unsigned char byte; | ||
| 173 | unsigned long flags; | ||
| 174 | |||
| 175 | if (reg < 0 || reg >= 8) | ||
| 176 | return 0; | ||
| 177 | |||
| 178 | spin_lock_irqsave(&mca_lock, flags); | ||
| 179 | if (mca_dev->pos_register) { | ||
| 180 | /* Disable adapter setup, enable motherboard setup */ | ||
| 181 | |||
| 182 | outb_p(0, MCA_ADAPTER_SETUP_REG); | ||
| 183 | outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); | ||
| 184 | |||
| 185 | byte = inb_p(MCA_POS_REG(reg)); | ||
| 186 | outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); | ||
| 187 | } else { | ||
| 188 | |||
| 189 | /* Make sure motherboard setup is off */ | ||
| 190 | |||
| 191 | outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); | ||
| 192 | |||
| 193 | /* Read the appropriate register */ | ||
| 194 | |||
| 195 | outb_p(0x8|(mca_dev->slot & 0xf), MCA_ADAPTER_SETUP_REG); | ||
| 196 | byte = inb_p(MCA_POS_REG(reg)); | ||
| 197 | outb_p(0, MCA_ADAPTER_SETUP_REG); | ||
| 198 | } | ||
| 199 | spin_unlock_irqrestore(&mca_lock, flags); | ||
| 200 | |||
| 201 | mca_dev->pos[reg] = byte; | ||
| 202 | |||
| 203 | return byte; | ||
| 204 | } | ||
| 205 | |||
| 206 | static void mca_pc_write_pos(struct mca_device *mca_dev, int reg, | ||
| 207 | unsigned char byte) | ||
| 208 | { | ||
| 209 | unsigned long flags; | ||
| 210 | |||
| 211 | if (reg < 0 || reg >= 8) | ||
| 212 | return; | ||
| 213 | |||
| 214 | spin_lock_irqsave(&mca_lock, flags); | ||
| 215 | |||
| 216 | /* Make sure motherboard setup is off */ | ||
| 217 | |||
| 218 | outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); | ||
| 219 | |||
| 220 | /* Read in the appropriate register */ | ||
| 221 | |||
| 222 | outb_p(0x8|(mca_dev->slot&0xf), MCA_ADAPTER_SETUP_REG); | ||
| 223 | outb_p(byte, MCA_POS_REG(reg)); | ||
| 224 | outb_p(0, MCA_ADAPTER_SETUP_REG); | ||
| 225 | |||
| 226 | spin_unlock_irqrestore(&mca_lock, flags); | ||
| 227 | |||
| 228 | /* Update the global register list, while we have the byte */ | ||
| 229 | |||
| 230 | mca_dev->pos[reg] = byte; | ||
| 231 | |||
| 232 | } | ||
| 233 | |||
| 234 | /* for the primary MCA bus, we have identity transforms */ | ||
| 235 | static int mca_dummy_transform_irq(struct mca_device *mca_dev, int irq) | ||
| 236 | { | ||
| 237 | return irq; | ||
| 238 | } | ||
| 239 | |||
| 240 | static int mca_dummy_transform_ioport(struct mca_device *mca_dev, int port) | ||
| 241 | { | ||
| 242 | return port; | ||
| 243 | } | ||
| 244 | |||
| 245 | static void *mca_dummy_transform_memory(struct mca_device *mca_dev, void *mem) | ||
| 246 | { | ||
| 247 | return mem; | ||
| 248 | } | ||
| 249 | |||
| 250 | |||
| 251 | static int __init mca_init(void) | ||
| 252 | { | ||
| 253 | unsigned int i, j; | ||
| 254 | struct mca_device *mca_dev; | ||
| 255 | unsigned char pos[8]; | ||
| 256 | short mca_builtin_scsi_ports[] = {0xf7, 0xfd, 0x00}; | ||
| 257 | struct mca_bus *bus; | ||
| 258 | |||
| 259 | /* | ||
| 260 | * WARNING: Be careful when making changes here. Putting an adapter | ||
| 261 | * and the motherboard simultaneously into setup mode may result in | ||
| 262 | * damage to chips (according to The Indispensable PC Hardware Book | ||
| 263 | * by Hans-Peter Messmer). Also, we disable system interrupts (so | ||
| 264 | * that we are not disturbed in the middle of this). | ||
| 265 | */ | ||
| 266 | |||
| 267 | /* Make sure the MCA bus is present */ | ||
| 268 | |||
| 269 | if (mca_system_init()) { | ||
| 270 | printk(KERN_ERR "MCA bus system initialisation failed\n"); | ||
| 271 | return -ENODEV; | ||
| 272 | } | ||
| 273 | |||
| 274 | if (!MCA_bus) | ||
| 275 | return -ENODEV; | ||
| 276 | |||
| 277 | printk(KERN_INFO "Micro Channel bus detected.\n"); | ||
| 278 | |||
| 279 | /* All MCA systems have at least a primary bus */ | ||
| 280 | bus = mca_attach_bus(MCA_PRIMARY_BUS); | ||
| 281 | if (!bus) | ||
| 282 | goto out_nomem; | ||
| 283 | bus->default_dma_mask = 0xffffffffLL; | ||
| 284 | bus->f.mca_write_pos = mca_pc_write_pos; | ||
| 285 | bus->f.mca_read_pos = mca_pc_read_pos; | ||
| 286 | bus->f.mca_transform_irq = mca_dummy_transform_irq; | ||
| 287 | bus->f.mca_transform_ioport = mca_dummy_transform_ioport; | ||
| 288 | bus->f.mca_transform_memory = mca_dummy_transform_memory; | ||
| 289 | |||
| 290 | /* get the motherboard device */ | ||
| 291 | mca_dev = kzalloc(sizeof(struct mca_device), GFP_KERNEL); | ||
| 292 | if (unlikely(!mca_dev)) | ||
| 293 | goto out_nomem; | ||
| 294 | |||
| 295 | /* | ||
| 296 | * We do not expect many MCA interrupts during initialization, | ||
| 297 | * but let us be safe: | ||
| 298 | */ | ||
| 299 | spin_lock_irq(&mca_lock); | ||
| 300 | |||
| 301 | /* Make sure adapter setup is off */ | ||
| 302 | |||
| 303 | outb_p(0, MCA_ADAPTER_SETUP_REG); | ||
| 304 | |||
| 305 | /* Read motherboard POS registers */ | ||
| 306 | |||
| 307 | mca_dev->pos_register = 0x7f; | ||
| 308 | outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); | ||
| 309 | mca_dev->name[0] = 0; | ||
| 310 | mca_read_and_store_pos(mca_dev->pos); | ||
| 311 | mca_configure_adapter_status(mca_dev); | ||
| 312 | /* fake POS and slot for a motherboard */ | ||
| 313 | mca_dev->pos_id = MCA_MOTHERBOARD_POS; | ||
| 314 | mca_dev->slot = MCA_MOTHERBOARD; | ||
| 315 | mca_register_device(MCA_PRIMARY_BUS, mca_dev); | ||
| 316 | |||
| 317 | mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); | ||
| 318 | if (unlikely(!mca_dev)) | ||
| 319 | goto out_unlock_nomem; | ||
| 320 | |||
| 321 | /* Put motherboard into video setup mode, read integrated video | ||
| 322 | * POS registers, and turn motherboard setup off. | ||
| 323 | */ | ||
| 324 | |||
| 325 | mca_dev->pos_register = 0xdf; | ||
| 326 | outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); | ||
| 327 | mca_dev->name[0] = 0; | ||
| 328 | mca_read_and_store_pos(mca_dev->pos); | ||
| 329 | mca_configure_adapter_status(mca_dev); | ||
| 330 | /* fake POS and slot for the integrated video */ | ||
| 331 | mca_dev->pos_id = MCA_INTEGVIDEO_POS; | ||
| 332 | mca_dev->slot = MCA_INTEGVIDEO; | ||
| 333 | mca_register_device(MCA_PRIMARY_BUS, mca_dev); | ||
| 334 | |||
| 335 | /* | ||
| 336 | * Put motherboard into scsi setup mode, read integrated scsi | ||
| 337 | * POS registers, and turn motherboard setup off. | ||
| 338 | * | ||
| 339 | * It seems there are two possible SCSI registers. Martin says that | ||
| 340 | * for the 56,57, 0xf7 is the one, but fails on the 76. | ||
| 341 | * Alfredo (apena@vnet.ibm.com) says | ||
| 342 | * 0xfd works on his machine. We'll try both of them. I figure it's | ||
| 343 | * a good bet that only one could be valid at a time. This could | ||
| 344 | * screw up though if one is used for something else on the other | ||
| 345 | * machine. | ||
| 346 | */ | ||
| 347 | |||
| 348 | for (i = 0; (which_scsi = mca_builtin_scsi_ports[i]) != 0; i++) { | ||
| 349 | outb_p(which_scsi, MCA_MOTHERBOARD_SETUP_REG); | ||
| 350 | if (mca_read_and_store_pos(pos)) | ||
| 351 | break; | ||
| 352 | } | ||
| 353 | if (which_scsi) { | ||
| 354 | /* found a scsi card */ | ||
| 355 | mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); | ||
| 356 | if (unlikely(!mca_dev)) | ||
| 357 | goto out_unlock_nomem; | ||
| 358 | |||
| 359 | for (j = 0; j < 8; j++) | ||
| 360 | mca_dev->pos[j] = pos[j]; | ||
| 361 | |||
| 362 | mca_configure_adapter_status(mca_dev); | ||
| 363 | /* fake POS and slot for integrated SCSI controller */ | ||
| 364 | mca_dev->pos_id = MCA_INTEGSCSI_POS; | ||
| 365 | mca_dev->slot = MCA_INTEGSCSI; | ||
| 366 | mca_dev->pos_register = which_scsi; | ||
| 367 | mca_register_device(MCA_PRIMARY_BUS, mca_dev); | ||
| 368 | } | ||
| 369 | |||
| 370 | /* Turn off motherboard setup */ | ||
| 371 | |||
| 372 | outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); | ||
| 373 | |||
| 374 | /* | ||
| 375 | * Now loop over MCA slots: put each adapter into setup mode, and | ||
| 376 | * read its POS registers. Then put adapter setup off. | ||
| 377 | */ | ||
| 378 | |||
| 379 | for (i = 0; i < MCA_MAX_SLOT_NR; i++) { | ||
| 380 | outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG); | ||
| 381 | if (!mca_read_and_store_pos(pos)) | ||
| 382 | continue; | ||
| 383 | |||
| 384 | mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); | ||
| 385 | if (unlikely(!mca_dev)) | ||
| 386 | goto out_unlock_nomem; | ||
| 387 | |||
| 388 | for (j = 0; j < 8; j++) | ||
| 389 | mca_dev->pos[j] = pos[j]; | ||
| 390 | |||
| 391 | mca_dev->driver_loaded = 0; | ||
| 392 | mca_dev->slot = i; | ||
| 393 | mca_dev->pos_register = 0; | ||
| 394 | mca_configure_adapter_status(mca_dev); | ||
| 395 | mca_register_device(MCA_PRIMARY_BUS, mca_dev); | ||
| 396 | } | ||
| 397 | outb_p(0, MCA_ADAPTER_SETUP_REG); | ||
| 398 | |||
| 399 | /* Enable interrupts and return memory start */ | ||
| 400 | spin_unlock_irq(&mca_lock); | ||
| 401 | |||
| 402 | for (i = 0; i < MCA_STANDARD_RESOURCES; i++) | ||
| 403 | request_resource(&ioport_resource, mca_standard_resources + i); | ||
| 404 | |||
| 405 | mca_do_proc_init(); | ||
| 406 | |||
| 407 | return 0; | ||
| 408 | |||
| 409 | out_unlock_nomem: | ||
| 410 | spin_unlock_irq(&mca_lock); | ||
| 411 | out_nomem: | ||
| 412 | printk(KERN_EMERG "Failed memory allocation in MCA setup!\n"); | ||
| 413 | return -ENOMEM; | ||
| 414 | } | ||
| 415 | |||
| 416 | subsys_initcall(mca_init); | ||
| 417 | |||
| 418 | /*--------------------------------------------------------------------*/ | ||
| 419 | |||
| 420 | static __kprobes void | ||
| 421 | mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) | ||
| 422 | { | ||
| 423 | int slot = mca_dev->slot; | ||
| 424 | |||
| 425 | if (slot == MCA_INTEGSCSI) { | ||
| 426 | printk(KERN_CRIT "NMI: caused by MCA integrated SCSI adapter (%s)\n", | ||
| 427 | mca_dev->name); | ||
| 428 | } else if (slot == MCA_INTEGVIDEO) { | ||
| 429 | printk(KERN_CRIT "NMI: caused by MCA integrated video adapter (%s)\n", | ||
| 430 | mca_dev->name); | ||
| 431 | } else if (slot == MCA_MOTHERBOARD) { | ||
| 432 | printk(KERN_CRIT "NMI: caused by motherboard (%s)\n", | ||
| 433 | mca_dev->name); | ||
| 434 | } | ||
| 435 | |||
| 436 | /* More info available in POS 6 and 7? */ | ||
| 437 | |||
| 438 | if (check_flag) { | ||
| 439 | unsigned char pos6, pos7; | ||
| 440 | |||
| 441 | pos6 = mca_device_read_pos(mca_dev, 6); | ||
| 442 | pos7 = mca_device_read_pos(mca_dev, 7); | ||
| 443 | |||
| 444 | printk(KERN_CRIT "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7); | ||
| 445 | } | ||
| 446 | |||
| 447 | } /* mca_handle_nmi_slot */ | ||
| 448 | |||
| 449 | /*--------------------------------------------------------------------*/ | ||
| 450 | |||
| 451 | static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data) | ||
| 452 | { | ||
| 453 | struct mca_device *mca_dev = to_mca_device(dev); | ||
| 454 | unsigned char pos5; | ||
| 455 | |||
| 456 | pos5 = mca_device_read_pos(mca_dev, 5); | ||
| 457 | |||
| 458 | if (!(pos5 & 0x80)) { | ||
| 459 | /* | ||
| 460 | * Bit 7 of POS 5 is reset when this adapter has a hardware | ||
| 461 | * error. Bit 7 it reset if there's error information | ||
| 462 | * available in POS 6 and 7. | ||
| 463 | */ | ||
| 464 | mca_handle_nmi_device(mca_dev, !(pos5 & 0x40)); | ||
| 465 | return 1; | ||
| 466 | } | ||
| 467 | return 0; | ||
| 468 | } | ||
| 469 | |||
| 470 | void __kprobes mca_handle_nmi(void) | ||
| 471 | { | ||
| 472 | /* | ||
| 473 | * First try - scan the various adapters and see if a specific | ||
| 474 | * adapter was responsible for the error. | ||
| 475 | */ | ||
| 476 | bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback); | ||
| 477 | } | ||
diff --git a/arch/x86/kernel/reboot_32.S b/arch/x86/kernel/reboot_32.S new file mode 100644 index 00000000000..1d5c46df0d7 --- /dev/null +++ b/arch/x86/kernel/reboot_32.S | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | #include <linux/linkage.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | #include <asm/segment.h> | ||
| 4 | #include <asm/page_types.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * The following code and data reboots the machine by switching to real | ||
| 8 | * mode and jumping to the BIOS reset entry point, as if the CPU has | ||
| 9 | * really been reset. The previous version asked the keyboard | ||
| 10 | * controller to pulse the CPU reset line, which is more thorough, but | ||
| 11 | * doesn't work with at least one type of 486 motherboard. It is easy | ||
| 12 | * to stop this code working; hence the copious comments. | ||
| 13 | * | ||
| 14 | * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax. | ||
| 15 | */ | ||
| 16 | .section ".x86_trampoline","a" | ||
| 17 | .balign 16 | ||
| 18 | .code32 | ||
| 19 | ENTRY(machine_real_restart_asm) | ||
| 20 | r_base = . | ||
| 21 | /* Get our own relocated address */ | ||
| 22 | call 1f | ||
| 23 | 1: popl %ebx | ||
| 24 | subl $(1b - r_base), %ebx | ||
| 25 | |||
| 26 | /* Compute the equivalent real-mode segment */ | ||
| 27 | movl %ebx, %ecx | ||
| 28 | shrl $4, %ecx | ||
| 29 | |||
| 30 | /* Patch post-real-mode segment jump */ | ||
| 31 | movw (dispatch_table - r_base)(%ebx,%eax,2),%ax | ||
| 32 | movw %ax, (101f - r_base)(%ebx) | ||
| 33 | movw %cx, (102f - r_base)(%ebx) | ||
| 34 | |||
| 35 | /* Set up the IDT for real mode. */ | ||
| 36 | lidtl (machine_real_restart_idt - r_base)(%ebx) | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Set up a GDT from which we can load segment descriptors for real | ||
| 40 | * mode. The GDT is not used in real mode; it is just needed here to | ||
| 41 | * prepare the descriptors. | ||
| 42 | */ | ||
| 43 | lgdtl (machine_real_restart_gdt - r_base)(%ebx) | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Load the data segment registers with 16-bit compatible values | ||
| 47 | */ | ||
| 48 | movl $16, %ecx | ||
| 49 | movl %ecx, %ds | ||
| 50 | movl %ecx, %es | ||
| 51 | movl %ecx, %fs | ||
| 52 | movl %ecx, %gs | ||
| 53 | movl %ecx, %ss | ||
| 54 | ljmpl $8, $1f - r_base | ||
| 55 | |||
| 56 | /* | ||
| 57 | * This is 16-bit protected mode code to disable paging and the cache, | ||
| 58 | * switch to real mode and jump to the BIOS reset code. | ||
| 59 | * | ||
| 60 | * The instruction that switches to real mode by writing to CR0 must be | ||
| 61 | * followed immediately by a far jump instruction, which set CS to a | ||
| 62 | * valid value for real mode, and flushes the prefetch queue to avoid | ||
| 63 | * running instructions that have already been decoded in protected | ||
| 64 | * mode. | ||
| 65 | * | ||
| 66 | * Clears all the flags except ET, especially PG (paging), PE | ||
| 67 | * (protected-mode enable) and TS (task switch for coprocessor state | ||
| 68 | * save). Flushes the TLB after paging has been disabled. Sets CD and | ||
| 69 | * NW, to disable the cache on a 486, and invalidates the cache. This | ||
| 70 | * is more like the state of a 486 after reset. I don't know if | ||
| 71 | * something else should be done for other chips. | ||
| 72 | * | ||
| 73 | * More could be done here to set up the registers as if a CPU reset had | ||
| 74 | * occurred; hopefully real BIOSs don't assume much. This is not the | ||
| 75 | * actual BIOS entry point, anyway (that is at 0xfffffff0). | ||
| 76 | * | ||
| 77 | * Most of this work is probably excessive, but it is what is tested. | ||
| 78 | */ | ||
| 79 | .code16 | ||
| 80 | 1: | ||
| 81 | xorl %ecx, %ecx | ||
| 82 | movl %cr0, %eax | ||
| 83 | andl $0x00000011, %eax | ||
| 84 | orl $0x60000000, %eax | ||
| 85 | movl %eax, %cr0 | ||
| 86 | movl %ecx, %cr3 | ||
| 87 | movl %cr0, %edx | ||
| 88 | andl $0x60000000, %edx /* If no cache bits -> no wbinvd */ | ||
| 89 | jz 2f | ||
| 90 | wbinvd | ||
| 91 | 2: | ||
| 92 | andb $0x10, %al | ||
| 93 | movl %eax, %cr0 | ||
| 94 | .byte 0xea /* ljmpw */ | ||
| 95 | 101: .word 0 /* Offset */ | ||
| 96 | 102: .word 0 /* Segment */ | ||
| 97 | |||
| 98 | bios: | ||
| 99 | ljmpw $0xf000, $0xfff0 | ||
| 100 | |||
| 101 | apm: | ||
| 102 | movw $0x1000, %ax | ||
| 103 | movw %ax, %ss | ||
| 104 | movw $0xf000, %sp | ||
| 105 | movw $0x5307, %ax | ||
| 106 | movw $0x0001, %bx | ||
| 107 | movw $0x0003, %cx | ||
| 108 | int $0x15 | ||
| 109 | |||
| 110 | END(machine_real_restart_asm) | ||
| 111 | |||
| 112 | .balign 16 | ||
| 113 | /* These must match <asm/reboot.h */ | ||
| 114 | dispatch_table: | ||
| 115 | .word bios - r_base | ||
| 116 | .word apm - r_base | ||
| 117 | END(dispatch_table) | ||
| 118 | |||
| 119 | .balign 16 | ||
| 120 | machine_real_restart_idt: | ||
| 121 | .word 0xffff /* Length - real mode default value */ | ||
| 122 | .long 0 /* Base - real mode default value */ | ||
| 123 | END(machine_real_restart_idt) | ||
| 124 | |||
| 125 | .balign 16 | ||
| 126 | ENTRY(machine_real_restart_gdt) | ||
| 127 | .quad 0 /* Self-pointer, filled in by PM code */ | ||
| 128 | .quad 0 /* 16-bit code segment, filled in by PM code */ | ||
| 129 | /* | ||
| 130 | * 16-bit data segment with the selector value 16 = 0x10 and | ||
| 131 | * base value 0x100; since this is consistent with real mode | ||
| 132 | * semantics we don't have to reload the segments once CR0.PE = 0. | ||
| 133 | */ | ||
| 134 | .quad GDT_ENTRY(0x0093, 0x100, 0xffff) | ||
| 135 | END(machine_real_restart_gdt) | ||
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c new file mode 100644 index 00000000000..0b0cb5fede1 --- /dev/null +++ b/arch/x86/kernel/sys_i386_32.c | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * This file contains various random system calls that | ||
| 3 | * have a non-standard calling sequence on the Linux/i386 | ||
| 4 | * platform. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/errno.h> | ||
| 8 | #include <linux/sched.h> | ||
| 9 | #include <linux/mm.h> | ||
| 10 | #include <linux/fs.h> | ||
| 11 | #include <linux/smp.h> | ||
| 12 | #include <linux/sem.h> | ||
| 13 | #include <linux/msg.h> | ||
| 14 | #include <linux/shm.h> | ||
| 15 | #include <linux/stat.h> | ||
| 16 | #include <linux/syscalls.h> | ||
| 17 | #include <linux/mman.h> | ||
| 18 | #include <linux/file.h> | ||
| 19 | #include <linux/utsname.h> | ||
| 20 | #include <linux/ipc.h> | ||
| 21 | |||
| 22 | #include <linux/uaccess.h> | ||
| 23 | #include <linux/unistd.h> | ||
| 24 | |||
| 25 | #include <asm/syscalls.h> | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Do a system call from kernel instead of calling sys_execve so we | ||
| 29 | * end up with proper pt_regs. | ||
| 30 | */ | ||
| 31 | int kernel_execve(const char *filename, | ||
| 32 | const char *const argv[], | ||
| 33 | const char *const envp[]) | ||
| 34 | { | ||
| 35 | long __res; | ||
| 36 | asm volatile ("int $0x80" | ||
| 37 | : "=a" (__res) | ||
| 38 | : "0" (__NR_execve), "b" (filename), "c" (argv), "d" (envp) : "memory"); | ||
| 39 | return __res; | ||
| 40 | } | ||
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S new file mode 100644 index 00000000000..bc19be332bc --- /dev/null +++ b/arch/x86/kernel/syscall_table_32.S | |||
| @@ -0,0 +1,348 @@ | |||
| 1 | ENTRY(sys_call_table) | ||
| 2 | .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ | ||
| 3 | .long sys_exit | ||
| 4 | .long ptregs_fork | ||
| 5 | .long sys_read | ||
| 6 | .long sys_write | ||
| 7 | .long sys_open /* 5 */ | ||
| 8 | .long sys_close | ||
| 9 | .long sys_waitpid | ||
| 10 | .long sys_creat | ||
| 11 | .long sys_link | ||
| 12 | .long sys_unlink /* 10 */ | ||
| 13 | .long ptregs_execve | ||
| 14 | .long sys_chdir | ||
| 15 | .long sys_time | ||
| 16 | .long sys_mknod | ||
| 17 | .long sys_chmod /* 15 */ | ||
| 18 | .long sys_lchown16 | ||
| 19 | .long sys_ni_syscall /* old break syscall holder */ | ||
| 20 | .long sys_stat | ||
| 21 | .long sys_lseek | ||
| 22 | .long sys_getpid /* 20 */ | ||
| 23 | .long sys_mount | ||
| 24 | .long sys_oldumount | ||
| 25 | .long sys_setuid16 | ||
| 26 | .long sys_getuid16 | ||
| 27 | .long sys_stime /* 25 */ | ||
| 28 | .long sys_ptrace | ||
| 29 | .long sys_alarm | ||
| 30 | .long sys_fstat | ||
| 31 | .long sys_pause | ||
| 32 | .long sys_utime /* 30 */ | ||
| 33 | .long sys_ni_syscall /* old stty syscall holder */ | ||
| 34 | .long sys_ni_syscall /* old gtty syscall holder */ | ||
| 35 | .long sys_access | ||
| 36 | .long sys_nice | ||
| 37 | .long sys_ni_syscall /* 35 - old ftime syscall holder */ | ||
| 38 | .long sys_sync | ||
| 39 | .long sys_kill | ||
| 40 | .long sys_rename | ||
| 41 | .long sys_mkdir | ||
| 42 | .long sys_rmdir /* 40 */ | ||
| 43 | .long sys_dup | ||
| 44 | .long sys_pipe | ||
| 45 | .long sys_times | ||
| 46 | .long sys_ni_syscall /* old prof syscall holder */ | ||
| 47 | .long sys_brk /* 45 */ | ||
| 48 | .long sys_setgid16 | ||
| 49 | .long sys_getgid16 | ||
| 50 | .long sys_signal | ||
| 51 | .long sys_geteuid16 | ||
| 52 | .long sys_getegid16 /* 50 */ | ||
| 53 | .long sys_acct | ||
| 54 | .long sys_umount /* recycled never used phys() */ | ||
| 55 | .long sys_ni_syscall /* old lock syscall holder */ | ||
| 56 | .long sys_ioctl | ||
| 57 | .long sys_fcntl /* 55 */ | ||
| 58 | .long sys_ni_syscall /* old mpx syscall holder */ | ||
| 59 | .long sys_setpgid | ||
| 60 | .long sys_ni_syscall /* old ulimit syscall holder */ | ||
| 61 | .long sys_olduname | ||
| 62 | .long sys_umask /* 60 */ | ||
| 63 | .long sys_chroot | ||
| 64 | .long sys_ustat | ||
| 65 | .long sys_dup2 | ||
| 66 | .long sys_getppid | ||
| 67 | .long sys_getpgrp /* 65 */ | ||
| 68 | .long sys_setsid | ||
| 69 | .long sys_sigaction | ||
| 70 | .long sys_sgetmask | ||
| 71 | .long sys_ssetmask | ||
| 72 | .long sys_setreuid16 /* 70 */ | ||
| 73 | .long sys_setregid16 | ||
| 74 | .long sys_sigsuspend | ||
| 75 | .long sys_sigpending | ||
| 76 | .long sys_sethostname | ||
| 77 | .long sys_setrlimit /* 75 */ | ||
| 78 | .long sys_old_getrlimit | ||
| 79 | .long sys_getrusage | ||
| 80 | .long sys_gettimeofday | ||
| 81 | .long sys_settimeofday | ||
| 82 | .long sys_getgroups16 /* 80 */ | ||
| 83 | .long sys_setgroups16 | ||
| 84 | .long sys_old_select | ||
| 85 | .long sys_symlink | ||
| 86 | .long sys_lstat | ||
| 87 | .long sys_readlink /* 85 */ | ||
| 88 | .long sys_uselib | ||
| 89 | .long sys_swapon | ||
| 90 | .long sys_reboot | ||
| 91 | .long sys_old_readdir | ||
| 92 | .long sys_old_mmap /* 90 */ | ||
| 93 | .long sys_munmap | ||
| 94 | .long sys_truncate | ||
| 95 | .long sys_ftruncate | ||
| 96 | .long sys_fchmod | ||
| 97 | .long sys_fchown16 /* 95 */ | ||
| 98 | .long sys_getpriority | ||
| 99 | .long sys_setpriority | ||
| 100 | .long sys_ni_syscall /* old profil syscall holder */ | ||
| 101 | .long sys_statfs | ||
| 102 | .long sys_fstatfs /* 100 */ | ||
| 103 | .long sys_ioperm | ||
| 104 | .long sys_socketcall | ||
| 105 | .long sys_syslog | ||
| 106 | .long sys_setitimer | ||
| 107 | .long sys_getitimer /* 105 */ | ||
| 108 | .long sys_newstat | ||
| 109 | .long sys_newlstat | ||
| 110 | .long sys_newfstat | ||
| 111 | .long sys_uname | ||
| 112 | .long ptregs_iopl /* 110 */ | ||
| 113 | .long sys_vhangup | ||
| 114 | .long sys_ni_syscall /* old "idle" system call */ | ||
| 115 | .long ptregs_vm86old | ||
| 116 | .long sys_wait4 | ||
| 117 | .long sys_swapoff /* 115 */ | ||
| 118 | .long sys_sysinfo | ||
| 119 | .long sys_ipc | ||
| 120 | .long sys_fsync | ||
| 121 | .long ptregs_sigreturn | ||
| 122 | .long ptregs_clone /* 120 */ | ||
| 123 | .long sys_setdomainname | ||
| 124 | .long sys_newuname | ||
| 125 | .long sys_modify_ldt | ||
| 126 | .long sys_adjtimex | ||
| 127 | .long sys_mprotect /* 125 */ | ||
| 128 | .long sys_sigprocmask | ||
| 129 | .long sys_ni_syscall /* old "create_module" */ | ||
| 130 | .long sys_init_module | ||
| 131 | .long sys_delete_module | ||
| 132 | .long sys_ni_syscall /* 130: old "get_kernel_syms" */ | ||
| 133 | .long sys_quotactl | ||
| 134 | .long sys_getpgid | ||
| 135 | .long sys_fchdir | ||
| 136 | .long sys_bdflush | ||
| 137 | .long sys_sysfs /* 135 */ | ||
| 138 | .long sys_personality | ||
| 139 | .long sys_ni_syscall /* reserved for afs_syscall */ | ||
| 140 | .long sys_setfsuid16 | ||
| 141 | .long sys_setfsgid16 | ||
| 142 | .long sys_llseek /* 140 */ | ||
| 143 | .long sys_getdents | ||
| 144 | .long sys_select | ||
| 145 | .long sys_flock | ||
| 146 | .long sys_msync | ||
| 147 | .long sys_readv /* 145 */ | ||
| 148 | .long sys_writev | ||
| 149 | .long sys_getsid | ||
| 150 | .long sys_fdatasync | ||
| 151 | .long sys_sysctl | ||
| 152 | .long sys_mlock /* 150 */ | ||
| 153 | .long sys_munlock | ||
| 154 | .long sys_mlockall | ||
| 155 | .long sys_munlockall | ||
| 156 | .long sys_sched_setparam | ||
| 157 | .long sys_sched_getparam /* 155 */ | ||
| 158 | .long sys_sched_setscheduler | ||
| 159 | .long sys_sched_getscheduler | ||
| 160 | .long sys_sched_yield | ||
| 161 | .long sys_sched_get_priority_max | ||
| 162 | .long sys_sched_get_priority_min /* 160 */ | ||
| 163 | .long sys_sched_rr_get_interval | ||
| 164 | .long sys_nanosleep | ||
| 165 | .long sys_mremap | ||
| 166 | .long sys_setresuid16 | ||
| 167 | .long sys_getresuid16 /* 165 */ | ||
| 168 | .long ptregs_vm86 | ||
| 169 | .long sys_ni_syscall /* Old sys_query_module */ | ||
| 170 | .long sys_poll | ||
| 171 | .long sys_ni_syscall /* Old nfsservctl */ | ||
| 172 | .long sys_setresgid16 /* 170 */ | ||
| 173 | .long sys_getresgid16 | ||
| 174 | .long sys_prctl | ||
| 175 | .long ptregs_rt_sigreturn | ||
| 176 | .long sys_rt_sigaction | ||
| 177 | .long sys_rt_sigprocmask /* 175 */ | ||
| 178 | .long sys_rt_sigpending | ||
| 179 | .long sys_rt_sigtimedwait | ||
| 180 | .long sys_rt_sigqueueinfo | ||
| 181 | .long sys_rt_sigsuspend | ||
| 182 | .long sys_pread64 /* 180 */ | ||
| 183 | .long sys_pwrite64 | ||
| 184 | .long sys_chown16 | ||
| 185 | .long sys_getcwd | ||
| 186 | .long sys_capget | ||
| 187 | .long sys_capset /* 185 */ | ||
| 188 | .long ptregs_sigaltstack | ||
| 189 | .long sys_sendfile | ||
| 190 | .long sys_ni_syscall /* reserved for streams1 */ | ||
| 191 | .long sys_ni_syscall /* reserved for streams2 */ | ||
| 192 | .long ptregs_vfork /* 190 */ | ||
| 193 | .long sys_getrlimit | ||
| 194 | .long sys_mmap_pgoff | ||
| 195 | .long sys_truncate64 | ||
| 196 | .long sys_ftruncate64 | ||
| 197 | .long sys_stat64 /* 195 */ | ||
| 198 | .long sys_lstat64 | ||
| 199 | .long sys_fstat64 | ||
| 200 | .long sys_lchown | ||
| 201 | .long sys_getuid | ||
| 202 | .long sys_getgid /* 200 */ | ||
| 203 | .long sys_geteuid | ||
| 204 | .long sys_getegid | ||
| 205 | .long sys_setreuid | ||
| 206 | .long sys_setregid | ||
| 207 | .long sys_getgroups /* 205 */ | ||
| 208 | .long sys_setgroups | ||
| 209 | .long sys_fchown | ||
| 210 | .long sys_setresuid | ||
| 211 | .long sys_getresuid | ||
| 212 | .long sys_setresgid /* 210 */ | ||
| 213 | .long sys_getresgid | ||
| 214 | .long sys_chown | ||
| 215 | .long sys_setuid | ||
| 216 | .long sys_setgid | ||
| 217 | .long sys_setfsuid /* 215 */ | ||
| 218 | .long sys_setfsgid | ||
| 219 | .long sys_pivot_root | ||
| 220 | .long sys_mincore | ||
| 221 | .long sys_madvise | ||
| 222 | .long sys_getdents64 /* 220 */ | ||
| 223 | .long sys_fcntl64 | ||
| 224 | .long sys_ni_syscall /* reserved for TUX */ | ||
| 225 | .long sys_ni_syscall | ||
| 226 | .long sys_gettid | ||
| 227 | .long sys_readahead /* 225 */ | ||
| 228 | .long sys_setxattr | ||
| 229 | .long sys_lsetxattr | ||
| 230 | .long sys_fsetxattr | ||
| 231 | .long sys_getxattr | ||
| 232 | .long sys_lgetxattr /* 230 */ | ||
| 233 | .long sys_fgetxattr | ||
| 234 | .long sys_listxattr | ||
| 235 | .long sys_llistxattr | ||
| 236 | .long sys_flistxattr | ||
| 237 | .long sys_removexattr /* 235 */ | ||
| 238 | .long sys_lremovexattr | ||
| 239 | .long sys_fremovexattr | ||
| 240 | .long sys_tkill | ||
| 241 | .long sys_sendfile64 | ||
| 242 | .long sys_futex /* 240 */ | ||
| 243 | .long sys_sched_setaffinity | ||
| 244 | .long sys_sched_getaffinity | ||
| 245 | .long sys_set_thread_area | ||
| 246 | .long sys_get_thread_area | ||
| 247 | .long sys_io_setup /* 245 */ | ||
| 248 | .long sys_io_destroy | ||
| 249 | .long sys_io_getevents | ||
| 250 | .long sys_io_submit | ||
| 251 | .long sys_io_cancel | ||
| 252 | .long sys_fadvise64 /* 250 */ | ||
| 253 | .long sys_ni_syscall | ||
| 254 | .long sys_exit_group | ||
| 255 | .long sys_lookup_dcookie | ||
| 256 | .long sys_epoll_create | ||
| 257 | .long sys_epoll_ctl /* 255 */ | ||
| 258 | .long sys_epoll_wait | ||
| 259 | .long sys_remap_file_pages | ||
| 260 | .long sys_set_tid_address | ||
| 261 | .long sys_timer_create | ||
| 262 | .long sys_timer_settime /* 260 */ | ||
| 263 | .long sys_timer_gettime | ||
| 264 | .long sys_timer_getoverrun | ||
| 265 | .long sys_timer_delete | ||
| 266 | .long sys_clock_settime | ||
| 267 | .long sys_clock_gettime /* 265 */ | ||
| 268 | .long sys_clock_getres | ||
| 269 | .long sys_clock_nanosleep | ||
| 270 | .long sys_statfs64 | ||
| 271 | .long sys_fstatfs64 | ||
| 272 | .long sys_tgkill /* 270 */ | ||
| 273 | .long sys_utimes | ||
| 274 | .long sys_fadvise64_64 | ||
| 275 | .long sys_ni_syscall /* sys_vserver */ | ||
| 276 | .long sys_mbind | ||
| 277 | .long sys_get_mempolicy | ||
| 278 | .long sys_set_mempolicy | ||
| 279 | .long sys_mq_open | ||
| 280 | .long sys_mq_unlink | ||
| 281 | .long sys_mq_timedsend | ||
| 282 | .long sys_mq_timedreceive /* 280 */ | ||
| 283 | .long sys_mq_notify | ||
| 284 | .long sys_mq_getsetattr | ||
| 285 | .long sys_kexec_load | ||
| 286 | .long sys_waitid | ||
| 287 | .long sys_ni_syscall /* 285 */ /* available */ | ||
| 288 | .long sys_add_key | ||
| 289 | .long sys_request_key | ||
| 290 | .long sys_keyctl | ||
| 291 | .long sys_ioprio_set | ||
| 292 | .long sys_ioprio_get /* 290 */ | ||
| 293 | .long sys_inotify_init | ||
| 294 | .long sys_inotify_add_watch | ||
| 295 | .long sys_inotify_rm_watch | ||
| 296 | .long sys_migrate_pages | ||
| 297 | .long sys_openat /* 295 */ | ||
| 298 | .long sys_mkdirat | ||
| 299 | .long sys_mknodat | ||
| 300 | .long sys_fchownat | ||
| 301 | .long sys_futimesat | ||
| 302 | .long sys_fstatat64 /* 300 */ | ||
| 303 | .long sys_unlinkat | ||
| 304 | .long sys_renameat | ||
| 305 | .long sys_linkat | ||
| 306 | .long sys_symlinkat | ||
| 307 | .long sys_readlinkat /* 305 */ | ||
| 308 | .long sys_fchmodat | ||
| 309 | .long sys_faccessat | ||
| 310 | .long sys_pselect6 | ||
| 311 | .long sys_ppoll | ||
| 312 | .long sys_unshare /* 310 */ | ||
| 313 | .long sys_set_robust_list | ||
| 314 | .long sys_get_robust_list | ||
| 315 | .long sys_splice | ||
| 316 | .long sys_sync_file_range | ||
| 317 | .long sys_tee /* 315 */ | ||
| 318 | .long sys_vmsplice | ||
| 319 | .long sys_move_pages | ||
| 320 | .long sys_getcpu | ||
| 321 | .long sys_epoll_pwait | ||
| 322 | .long sys_utimensat /* 320 */ | ||
| 323 | .long sys_signalfd | ||
| 324 | .long sys_timerfd_create | ||
| 325 | .long sys_eventfd | ||
| 326 | .long sys_fallocate | ||
| 327 | .long sys_timerfd_settime /* 325 */ | ||
| 328 | .long sys_timerfd_gettime | ||
| 329 | .long sys_signalfd4 | ||
| 330 | .long sys_eventfd2 | ||
| 331 | .long sys_epoll_create1 | ||
| 332 | .long sys_dup3 /* 330 */ | ||
| 333 | .long sys_pipe2 | ||
| 334 | .long sys_inotify_init1 | ||
| 335 | .long sys_preadv | ||
| 336 | .long sys_pwritev | ||
| 337 | .long sys_rt_tgsigqueueinfo /* 335 */ | ||
| 338 | .long sys_perf_event_open | ||
| 339 | .long sys_recvmmsg | ||
| 340 | .long sys_fanotify_init | ||
| 341 | .long sys_fanotify_mark | ||
| 342 | .long sys_prlimit64 /* 340 */ | ||
| 343 | .long sys_name_to_handle_at | ||
| 344 | .long sys_open_by_handle_at | ||
| 345 | .long sys_clock_adjtime | ||
| 346 | .long sys_syncfs | ||
| 347 | .long sys_sendmmsg /* 345 */ | ||
| 348 | .long sys_setns | ||
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c new file mode 100644 index 00000000000..a91ae7709b4 --- /dev/null +++ b/arch/x86/kernel/trampoline.c | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | #include <linux/io.h> | ||
| 2 | #include <linux/memblock.h> | ||
| 3 | |||
| 4 | #include <asm/trampoline.h> | ||
| 5 | #include <asm/cacheflush.h> | ||
| 6 | #include <asm/pgtable.h> | ||
| 7 | |||
| 8 | unsigned char *x86_trampoline_base; | ||
| 9 | |||
| 10 | void __init setup_trampolines(void) | ||
| 11 | { | ||
| 12 | phys_addr_t mem; | ||
| 13 | size_t size = PAGE_ALIGN(x86_trampoline_end - x86_trampoline_start); | ||
| 14 | |||
| 15 | /* Has to be in very low memory so we can execute real-mode AP code. */ | ||
| 16 | mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); | ||
| 17 | if (mem == MEMBLOCK_ERROR) | ||
| 18 | panic("Cannot allocate trampoline\n"); | ||
| 19 | |||
| 20 | x86_trampoline_base = __va(mem); | ||
| 21 | memblock_x86_reserve_range(mem, mem + size, "TRAMPOLINE"); | ||
| 22 | |||
| 23 | printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n", | ||
| 24 | x86_trampoline_base, (unsigned long long)mem, size); | ||
| 25 | |||
| 26 | memcpy(x86_trampoline_base, x86_trampoline_start, size); | ||
| 27 | } | ||
| 28 | |||
| 29 | /* | ||
| 30 | * setup_trampolines() gets called very early, to guarantee the | ||
| 31 | * availability of low memory. This is before the proper kernel page | ||
| 32 | * tables are set up, so we cannot set page permissions in that | ||
| 33 | * function. Thus, we use an arch_initcall instead. | ||
| 34 | */ | ||
| 35 | static int __init configure_trampolines(void) | ||
| 36 | { | ||
| 37 | size_t size = PAGE_ALIGN(x86_trampoline_end - x86_trampoline_start); | ||
| 38 | |||
| 39 | set_memory_x((unsigned long)x86_trampoline_base, size >> PAGE_SHIFT); | ||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | arch_initcall(configure_trampolines); | ||
diff --git a/arch/x86/kernel/trampoline_32.S b/arch/x86/kernel/trampoline_32.S new file mode 100644 index 00000000000..451c0a7ef7f --- /dev/null +++ b/arch/x86/kernel/trampoline_32.S | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Trampoline.S Derived from Setup.S by Linus Torvalds | ||
| 4 | * | ||
| 5 | * 4 Jan 1997 Michael Chastain: changed to gnu as. | ||
| 6 | * | ||
| 7 | * This is only used for booting secondary CPUs in SMP machine | ||
| 8 | * | ||
| 9 | * Entry: CS:IP point to the start of our code, we are | ||
| 10 | * in real mode with no stack, but the rest of the | ||
| 11 | * trampoline page to make our stack and everything else | ||
| 12 | * is a mystery. | ||
| 13 | * | ||
| 14 | * We jump into arch/x86/kernel/head_32.S. | ||
| 15 | * | ||
| 16 | * On entry to trampoline_data, the processor is in real mode | ||
| 17 | * with 16-bit addressing and 16-bit data. CS has some value | ||
| 18 | * and IP is zero. Thus, data addresses need to be absolute | ||
| 19 | * (no relocation) and are taken with regard to r_base. | ||
| 20 | * | ||
| 21 | * If you work on this file, check the object module with | ||
| 22 | * objdump --reloc to make sure there are no relocation | ||
| 23 | * entries except for: | ||
| 24 | * | ||
| 25 | * TYPE VALUE | ||
| 26 | * R_386_32 startup_32_smp | ||
| 27 | * R_386_32 boot_gdt | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <linux/linkage.h> | ||
| 31 | #include <linux/init.h> | ||
| 32 | #include <asm/segment.h> | ||
| 33 | #include <asm/page_types.h> | ||
| 34 | |||
| 35 | #ifdef CONFIG_SMP | ||
| 36 | |||
| 37 | .section ".x86_trampoline","a" | ||
| 38 | .balign PAGE_SIZE | ||
| 39 | .code16 | ||
| 40 | |||
| 41 | ENTRY(trampoline_data) | ||
| 42 | r_base = . | ||
| 43 | wbinvd # Needed for NUMA-Q should be harmless for others | ||
| 44 | mov %cs, %ax # Code and data in the same place | ||
| 45 | mov %ax, %ds | ||
| 46 | |||
| 47 | cli # We should be safe anyway | ||
| 48 | |||
| 49 | movl $0xA5A5A5A5, trampoline_status - r_base | ||
| 50 | # write marker for master knows we're running | ||
| 51 | |||
| 52 | /* GDT tables in non default location kernel can be beyond 16MB and | ||
| 53 | * lgdt will not be able to load the address as in real mode default | ||
| 54 | * operand size is 16bit. Use lgdtl instead to force operand size | ||
| 55 | * to 32 bit. | ||
| 56 | */ | ||
| 57 | |||
| 58 | lidtl boot_idt_descr - r_base # load idt with 0, 0 | ||
| 59 | lgdtl boot_gdt_descr - r_base # load gdt with whatever is appropriate | ||
| 60 | |||
| 61 | xor %ax, %ax | ||
| 62 | inc %ax # protected mode (PE) bit | ||
| 63 | lmsw %ax # into protected mode | ||
| 64 | # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S | ||
| 65 | ljmpl $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET) | ||
| 66 | |||
| 67 | # These need to be in the same 64K segment as the above; | ||
| 68 | # hence we don't use the boot_gdt_descr defined in head.S | ||
| 69 | boot_gdt_descr: | ||
| 70 | .word __BOOT_DS + 7 # gdt limit | ||
| 71 | .long boot_gdt - __PAGE_OFFSET # gdt base | ||
| 72 | |||
| 73 | boot_idt_descr: | ||
| 74 | .word 0 # idt limit = 0 | ||
| 75 | .long 0 # idt base = 0L | ||
| 76 | |||
| 77 | ENTRY(trampoline_status) | ||
| 78 | .long 0 | ||
| 79 | |||
| 80 | .globl trampoline_end | ||
| 81 | trampoline_end: | ||
| 82 | |||
| 83 | #endif /* CONFIG_SMP */ | ||
diff --git a/arch/x86/kernel/trampoline_64.S b/arch/x86/kernel/trampoline_64.S new file mode 100644 index 00000000000..09ff51799e9 --- /dev/null +++ b/arch/x86/kernel/trampoline_64.S | |||
| @@ -0,0 +1,171 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Trampoline.S Derived from Setup.S by Linus Torvalds | ||
| 4 | * | ||
| 5 | * 4 Jan 1997 Michael Chastain: changed to gnu as. | ||
| 6 | * 15 Sept 2005 Eric Biederman: 64bit PIC support | ||
| 7 | * | ||
| 8 | * Entry: CS:IP point to the start of our code, we are | ||
| 9 | * in real mode with no stack, but the rest of the | ||
| 10 | * trampoline page to make our stack and everything else | ||
| 11 | * is a mystery. | ||
| 12 | * | ||
| 13 | * On entry to trampoline_data, the processor is in real mode | ||
| 14 | * with 16-bit addressing and 16-bit data. CS has some value | ||
| 15 | * and IP is zero. Thus, data addresses need to be absolute | ||
| 16 | * (no relocation) and are taken with regard to r_base. | ||
| 17 | * | ||
| 18 | * With the addition of trampoline_level4_pgt this code can | ||
| 19 | * now enter a 64bit kernel that lives at arbitrary 64bit | ||
| 20 | * physical addresses. | ||
| 21 | * | ||
| 22 | * If you work on this file, check the object module with objdump | ||
| 23 | * --full-contents --reloc to make sure there are no relocation | ||
| 24 | * entries. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/linkage.h> | ||
| 28 | #include <linux/init.h> | ||
| 29 | #include <asm/pgtable_types.h> | ||
| 30 | #include <asm/page_types.h> | ||
| 31 | #include <asm/msr.h> | ||
| 32 | #include <asm/segment.h> | ||
| 33 | #include <asm/processor-flags.h> | ||
| 34 | |||
| 35 | .section ".x86_trampoline","a" | ||
| 36 | .balign PAGE_SIZE | ||
| 37 | .code16 | ||
| 38 | |||
| 39 | ENTRY(trampoline_data) | ||
| 40 | r_base = . | ||
| 41 | cli # We should be safe anyway | ||
| 42 | wbinvd | ||
| 43 | mov %cs, %ax # Code and data in the same place | ||
| 44 | mov %ax, %ds | ||
| 45 | mov %ax, %es | ||
| 46 | mov %ax, %ss | ||
| 47 | |||
| 48 | |||
| 49 | movl $0xA5A5A5A5, trampoline_status - r_base | ||
| 50 | # write marker for master knows we're running | ||
| 51 | |||
| 52 | # Setup stack | ||
| 53 | movw $(trampoline_stack_end - r_base), %sp | ||
| 54 | |||
| 55 | call verify_cpu # Verify the cpu supports long mode | ||
| 56 | testl %eax, %eax # Check for return code | ||
| 57 | jnz no_longmode | ||
| 58 | |||
| 59 | mov %cs, %ax | ||
| 60 | movzx %ax, %esi # Find the 32bit trampoline location | ||
| 61 | shll $4, %esi | ||
| 62 | |||
| 63 | # Fixup the absolute vectors | ||
| 64 | leal (startup_32 - r_base)(%esi), %eax | ||
| 65 | movl %eax, startup_32_vector - r_base | ||
| 66 | leal (startup_64 - r_base)(%esi), %eax | ||
| 67 | movl %eax, startup_64_vector - r_base | ||
| 68 | leal (tgdt - r_base)(%esi), %eax | ||
| 69 | movl %eax, (tgdt + 2 - r_base) | ||
| 70 | |||
| 71 | /* | ||
| 72 | * GDT tables in non default location kernel can be beyond 16MB and | ||
| 73 | * lgdt will not be able to load the address as in real mode default | ||
| 74 | * operand size is 16bit. Use lgdtl instead to force operand size | ||
| 75 | * to 32 bit. | ||
| 76 | */ | ||
| 77 | |||
| 78 | lidtl tidt - r_base # load idt with 0, 0 | ||
| 79 | lgdtl tgdt - r_base # load gdt with whatever is appropriate | ||
| 80 | |||
| 81 | mov $X86_CR0_PE, %ax # protected mode (PE) bit | ||
| 82 | lmsw %ax # into protected mode | ||
| 83 | |||
| 84 | # flush prefetch and jump to startup_32 | ||
| 85 | ljmpl *(startup_32_vector - r_base) | ||
| 86 | |||
| 87 | .code32 | ||
| 88 | .balign 4 | ||
| 89 | startup_32: | ||
| 90 | movl $__KERNEL_DS, %eax # Initialize the %ds segment register | ||
| 91 | movl %eax, %ds | ||
| 92 | |||
| 93 | movl $X86_CR4_PAE, %eax | ||
| 94 | movl %eax, %cr4 # Enable PAE mode | ||
| 95 | |||
| 96 | # Setup trampoline 4 level pagetables | ||
| 97 | leal (trampoline_level4_pgt - r_base)(%esi), %eax | ||
| 98 | movl %eax, %cr3 | ||
| 99 | |||
| 100 | movl $MSR_EFER, %ecx | ||
| 101 | movl $(1 << _EFER_LME), %eax # Enable Long Mode | ||
| 102 | xorl %edx, %edx | ||
| 103 | wrmsr | ||
| 104 | |||
| 105 | # Enable paging and in turn activate Long Mode | ||
| 106 | # Enable protected mode | ||
| 107 | movl $(X86_CR0_PG | X86_CR0_PE), %eax | ||
| 108 | movl %eax, %cr0 | ||
| 109 | |||
| 110 | /* | ||
| 111 | * At this point we're in long mode but in 32bit compatibility mode | ||
| 112 | * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn | ||
| 113 | * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use | ||
| 114 | * the new gdt/idt that has __KERNEL_CS with CS.L = 1. | ||
| 115 | */ | ||
| 116 | ljmp *(startup_64_vector - r_base)(%esi) | ||
| 117 | |||
| 118 | .code64 | ||
| 119 | .balign 4 | ||
| 120 | startup_64: | ||
| 121 | # Now jump into the kernel using virtual addresses | ||
| 122 | movq $secondary_startup_64, %rax | ||
| 123 | jmp *%rax | ||
| 124 | |||
| 125 | .code16 | ||
| 126 | no_longmode: | ||
| 127 | hlt | ||
| 128 | jmp no_longmode | ||
| 129 | #include "verify_cpu.S" | ||
| 130 | |||
| 131 | .balign 4 | ||
| 132 | # Careful these need to be in the same 64K segment as the above; | ||
| 133 | tidt: | ||
| 134 | .word 0 # idt limit = 0 | ||
| 135 | .word 0, 0 # idt base = 0L | ||
| 136 | |||
| 137 | # Duplicate the global descriptor table | ||
| 138 | # so the kernel can live anywhere | ||
| 139 | .balign 4 | ||
| 140 | tgdt: | ||
| 141 | .short tgdt_end - tgdt # gdt limit | ||
| 142 | .long tgdt - r_base | ||
| 143 | .short 0 | ||
| 144 | .quad 0x00cf9b000000ffff # __KERNEL32_CS | ||
| 145 | .quad 0x00af9b000000ffff # __KERNEL_CS | ||
| 146 | .quad 0x00cf93000000ffff # __KERNEL_DS | ||
| 147 | tgdt_end: | ||
| 148 | |||
| 149 | .balign 4 | ||
| 150 | startup_32_vector: | ||
| 151 | .long startup_32 - r_base | ||
| 152 | .word __KERNEL32_CS, 0 | ||
| 153 | |||
| 154 | .balign 4 | ||
| 155 | startup_64_vector: | ||
| 156 | .long startup_64 - r_base | ||
| 157 | .word __KERNEL_CS, 0 | ||
| 158 | |||
| 159 | .balign 4 | ||
| 160 | ENTRY(trampoline_status) | ||
| 161 | .long 0 | ||
| 162 | |||
| 163 | trampoline_stack: | ||
| 164 | .org 0x1000 | ||
| 165 | trampoline_stack_end: | ||
| 166 | ENTRY(trampoline_level4_pgt) | ||
| 167 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
| 168 | .fill 510,8,0 | ||
| 169 | .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
| 170 | |||
| 171 | ENTRY(trampoline_end) | ||
diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h new file mode 100644 index 00000000000..64bc6ea78d9 --- /dev/null +++ b/arch/x86/kvm/kvm_timer.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | |||
| 2 | struct kvm_timer { | ||
| 3 | struct hrtimer timer; | ||
| 4 | s64 period; /* unit: ns */ | ||
| 5 | atomic_t pending; /* accumulated triggered timers */ | ||
| 6 | bool reinject; | ||
| 7 | struct kvm_timer_ops *t_ops; | ||
| 8 | struct kvm *kvm; | ||
| 9 | struct kvm_vcpu *vcpu; | ||
| 10 | }; | ||
| 11 | |||
| 12 | struct kvm_timer_ops { | ||
| 13 | bool (*is_periodic)(struct kvm_timer *); | ||
| 14 | }; | ||
| 15 | |||
| 16 | enum hrtimer_restart kvm_timer_fn(struct hrtimer *data); | ||
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c new file mode 100644 index 00000000000..ae432ea1cd8 --- /dev/null +++ b/arch/x86/kvm/timer.c | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /* | ||
| 2 | * Kernel-based Virtual Machine driver for Linux | ||
| 3 | * | ||
| 4 | * This module enables machines with Intel VT-x extensions to run virtual | ||
| 5 | * machines without emulation or binary translation. | ||
| 6 | * | ||
| 7 | * timer support | ||
| 8 | * | ||
| 9 | * Copyright 2010 Red Hat, Inc. and/or its affiliates. | ||
| 10 | * | ||
| 11 | * This work is licensed under the terms of the GNU GPL, version 2. See | ||
| 12 | * the COPYING file in the top-level directory. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kvm_host.h> | ||
| 16 | #include <linux/kvm.h> | ||
| 17 | #include <linux/hrtimer.h> | ||
| 18 | #include <linux/atomic.h> | ||
| 19 | #include "kvm_timer.h" | ||
| 20 | |||
| 21 | static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer) | ||
| 22 | { | ||
| 23 | int restart_timer = 0; | ||
| 24 | wait_queue_head_t *q = &vcpu->wq; | ||
| 25 | |||
| 26 | /* | ||
| 27 | * There is a race window between reading and incrementing, but we do | ||
| 28 | * not care about potentially losing timer events in the !reinject | ||
| 29 | * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked | ||
| 30 | * in vcpu_enter_guest. | ||
| 31 | */ | ||
| 32 | if (ktimer->reinject || !atomic_read(&ktimer->pending)) { | ||
| 33 | atomic_inc(&ktimer->pending); | ||
| 34 | /* FIXME: this code should not know anything about vcpus */ | ||
| 35 | kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); | ||
| 36 | } | ||
| 37 | |||
| 38 | if (waitqueue_active(q)) | ||
| 39 | wake_up_interruptible(q); | ||
| 40 | |||
| 41 | if (ktimer->t_ops->is_periodic(ktimer)) { | ||
| 42 | hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); | ||
| 43 | restart_timer = 1; | ||
| 44 | } | ||
| 45 | |||
| 46 | return restart_timer; | ||
| 47 | } | ||
| 48 | |||
| 49 | enum hrtimer_restart kvm_timer_fn(struct hrtimer *data) | ||
| 50 | { | ||
| 51 | int restart_timer; | ||
| 52 | struct kvm_vcpu *vcpu; | ||
| 53 | struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); | ||
| 54 | |||
| 55 | vcpu = ktimer->vcpu; | ||
| 56 | if (!vcpu) | ||
| 57 | return HRTIMER_NORESTART; | ||
| 58 | |||
| 59 | restart_timer = __kvm_timer_fn(vcpu, ktimer); | ||
| 60 | if (restart_timer) | ||
| 61 | return HRTIMER_RESTART; | ||
| 62 | else | ||
| 63 | return HRTIMER_NORESTART; | ||
| 64 | } | ||
| 65 | |||
diff --git a/arch/x86/lib/cmpxchg.c b/arch/x86/lib/cmpxchg.c new file mode 100644 index 00000000000..5d619f6df3e --- /dev/null +++ b/arch/x86/lib/cmpxchg.c | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * cmpxchg*() fallbacks for CPU not supporting these instructions | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <linux/kernel.h> | ||
| 6 | #include <linux/smp.h> | ||
| 7 | #include <linux/module.h> | ||
| 8 | |||
| 9 | #ifndef CONFIG_X86_CMPXCHG | ||
| 10 | unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new) | ||
| 11 | { | ||
| 12 | u8 prev; | ||
| 13 | unsigned long flags; | ||
| 14 | |||
| 15 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
| 16 | local_irq_save(flags); | ||
| 17 | prev = *(u8 *)ptr; | ||
| 18 | if (prev == old) | ||
| 19 | *(u8 *)ptr = new; | ||
| 20 | local_irq_restore(flags); | ||
| 21 | return prev; | ||
| 22 | } | ||
| 23 | EXPORT_SYMBOL(cmpxchg_386_u8); | ||
| 24 | |||
| 25 | unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new) | ||
| 26 | { | ||
| 27 | u16 prev; | ||
| 28 | unsigned long flags; | ||
| 29 | |||
| 30 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
| 31 | local_irq_save(flags); | ||
| 32 | prev = *(u16 *)ptr; | ||
| 33 | if (prev == old) | ||
| 34 | *(u16 *)ptr = new; | ||
| 35 | local_irq_restore(flags); | ||
| 36 | return prev; | ||
| 37 | } | ||
| 38 | EXPORT_SYMBOL(cmpxchg_386_u16); | ||
| 39 | |||
| 40 | unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new) | ||
| 41 | { | ||
| 42 | u32 prev; | ||
| 43 | unsigned long flags; | ||
| 44 | |||
| 45 | /* Poor man's cmpxchg for 386. Unsuitable for SMP */ | ||
| 46 | local_irq_save(flags); | ||
| 47 | prev = *(u32 *)ptr; | ||
| 48 | if (prev == old) | ||
| 49 | *(u32 *)ptr = new; | ||
| 50 | local_irq_restore(flags); | ||
| 51 | return prev; | ||
| 52 | } | ||
| 53 | EXPORT_SYMBOL(cmpxchg_386_u32); | ||
| 54 | #endif | ||
diff --git a/arch/x86/mm/memblock.c b/arch/x86/mm/memblock.c new file mode 100644 index 00000000000..992da5ec5a6 --- /dev/null +++ b/arch/x86/mm/memblock.c | |||
| @@ -0,0 +1,348 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/types.h> | ||
| 3 | #include <linux/init.h> | ||
| 4 | #include <linux/bitops.h> | ||
| 5 | #include <linux/memblock.h> | ||
| 6 | #include <linux/bootmem.h> | ||
| 7 | #include <linux/mm.h> | ||
| 8 | #include <linux/range.h> | ||
| 9 | |||
| 10 | /* Check for already reserved areas */ | ||
| 11 | bool __init memblock_x86_check_reserved_size(u64 *addrp, u64 *sizep, u64 align) | ||
| 12 | { | ||
| 13 | struct memblock_region *r; | ||
| 14 | u64 addr = *addrp, last; | ||
| 15 | u64 size = *sizep; | ||
| 16 | bool changed = false; | ||
| 17 | |||
| 18 | again: | ||
| 19 | last = addr + size; | ||
| 20 | for_each_memblock(reserved, r) { | ||
| 21 | if (last > r->base && addr < r->base) { | ||
| 22 | size = r->base - addr; | ||
| 23 | changed = true; | ||
| 24 | goto again; | ||
| 25 | } | ||
| 26 | if (last > (r->base + r->size) && addr < (r->base + r->size)) { | ||
| 27 | addr = round_up(r->base + r->size, align); | ||
| 28 | size = last - addr; | ||
| 29 | changed = true; | ||
| 30 | goto again; | ||
| 31 | } | ||
| 32 | if (last <= (r->base + r->size) && addr >= r->base) { | ||
| 33 | *sizep = 0; | ||
| 34 | return false; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | if (changed) { | ||
| 38 | *addrp = addr; | ||
| 39 | *sizep = size; | ||
| 40 | } | ||
| 41 | return changed; | ||
| 42 | } | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Find next free range after start, and size is returned in *sizep | ||
| 46 | */ | ||
| 47 | u64 __init memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align) | ||
| 48 | { | ||
| 49 | struct memblock_region *r; | ||
| 50 | |||
| 51 | for_each_memblock(memory, r) { | ||
| 52 | u64 ei_start = r->base; | ||
| 53 | u64 ei_last = ei_start + r->size; | ||
| 54 | u64 addr; | ||
| 55 | |||
| 56 | addr = round_up(ei_start, align); | ||
| 57 | if (addr < start) | ||
| 58 | addr = round_up(start, align); | ||
| 59 | if (addr >= ei_last) | ||
| 60 | continue; | ||
| 61 | *sizep = ei_last - addr; | ||
| 62 | while (memblock_x86_check_reserved_size(&addr, sizep, align)) | ||
| 63 | ; | ||
| 64 | |||
| 65 | if (*sizep) | ||
| 66 | return addr; | ||
| 67 | } | ||
| 68 | |||
| 69 | return MEMBLOCK_ERROR; | ||
| 70 | } | ||
| 71 | |||
| 72 | static __init struct range *find_range_array(int count) | ||
| 73 | { | ||
| 74 | u64 end, size, mem; | ||
| 75 | struct range *range; | ||
| 76 | |||
| 77 | size = sizeof(struct range) * count; | ||
| 78 | end = memblock.current_limit; | ||
| 79 | |||
| 80 | mem = memblock_find_in_range(0, end, size, sizeof(struct range)); | ||
| 81 | if (mem == MEMBLOCK_ERROR) | ||
| 82 | panic("can not find more space for range array"); | ||
| 83 | |||
| 84 | /* | ||
| 85 | * This range is tempoaray, so don't reserve it, it will not be | ||
| 86 | * overlapped because We will not alloccate new buffer before | ||
| 87 | * We discard this one | ||
| 88 | */ | ||
| 89 | range = __va(mem); | ||
| 90 | memset(range, 0, size); | ||
| 91 | |||
| 92 | return range; | ||
| 93 | } | ||
| 94 | |||
| 95 | static void __init memblock_x86_subtract_reserved(struct range *range, int az) | ||
| 96 | { | ||
| 97 | u64 final_start, final_end; | ||
| 98 | struct memblock_region *r; | ||
| 99 | |||
| 100 | /* Take out region array itself at first*/ | ||
| 101 | memblock_free_reserved_regions(); | ||
| 102 | |||
| 103 | memblock_dbg("Subtract (%ld early reservations)\n", memblock.reserved.cnt); | ||
| 104 | |||
| 105 | for_each_memblock(reserved, r) { | ||
| 106 | memblock_dbg(" [%010llx-%010llx]\n", (u64)r->base, (u64)r->base + r->size - 1); | ||
| 107 | final_start = PFN_DOWN(r->base); | ||
| 108 | final_end = PFN_UP(r->base + r->size); | ||
| 109 | if (final_start >= final_end) | ||
| 110 | continue; | ||
| 111 | subtract_range(range, az, final_start, final_end); | ||
| 112 | } | ||
| 113 | |||
| 114 | /* Put region array back ? */ | ||
| 115 | memblock_reserve_reserved_regions(); | ||
| 116 | } | ||
| 117 | |||
| 118 | struct count_data { | ||
| 119 | int nr; | ||
| 120 | }; | ||
| 121 | |||
| 122 | static int __init count_work_fn(unsigned long start_pfn, | ||
| 123 | unsigned long end_pfn, void *datax) | ||
| 124 | { | ||
| 125 | struct count_data *data = datax; | ||
| 126 | |||
| 127 | data->nr++; | ||
| 128 | |||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int __init count_early_node_map(int nodeid) | ||
| 133 | { | ||
| 134 | struct count_data data; | ||
| 135 | |||
| 136 | data.nr = 0; | ||
| 137 | work_with_active_regions(nodeid, count_work_fn, &data); | ||
| 138 | |||
| 139 | return data.nr; | ||
| 140 | } | ||
| 141 | |||
| 142 | int __init __get_free_all_memory_range(struct range **rangep, int nodeid, | ||
| 143 | unsigned long start_pfn, unsigned long end_pfn) | ||
| 144 | { | ||
| 145 | int count; | ||
| 146 | struct range *range; | ||
| 147 | int nr_range; | ||
| 148 | |||
| 149 | count = (memblock.reserved.cnt + count_early_node_map(nodeid)) * 2; | ||
| 150 | |||
| 151 | range = find_range_array(count); | ||
| 152 | nr_range = 0; | ||
| 153 | |||
| 154 | /* | ||
| 155 | * Use early_node_map[] and memblock.reserved.region to get range array | ||
| 156 | * at first | ||
| 157 | */ | ||
| 158 | nr_range = add_from_early_node_map(range, count, nr_range, nodeid); | ||
| 159 | subtract_range(range, count, 0, start_pfn); | ||
| 160 | subtract_range(range, count, end_pfn, -1ULL); | ||
| 161 | |||
| 162 | memblock_x86_subtract_reserved(range, count); | ||
| 163 | nr_range = clean_sort_range(range, count); | ||
| 164 | |||
| 165 | *rangep = range; | ||
| 166 | return nr_range; | ||
| 167 | } | ||
| 168 | |||
| 169 | int __init get_free_all_memory_range(struct range **rangep, int nodeid) | ||
| 170 | { | ||
| 171 | unsigned long end_pfn = -1UL; | ||
| 172 | |||
| 173 | #ifdef CONFIG_X86_32 | ||
| 174 | end_pfn = max_low_pfn; | ||
| 175 | #endif | ||
| 176 | return __get_free_all_memory_range(rangep, nodeid, 0, end_pfn); | ||
| 177 | } | ||
| 178 | |||
| 179 | static u64 __init __memblock_x86_memory_in_range(u64 addr, u64 limit, bool get_free) | ||
| 180 | { | ||
| 181 | int i, count; | ||
| 182 | struct range *range; | ||
| 183 | int nr_range; | ||
| 184 | u64 final_start, final_end; | ||
| 185 | u64 free_size; | ||
| 186 | struct memblock_region *r; | ||
| 187 | |||
| 188 | count = (memblock.reserved.cnt + memblock.memory.cnt) * 2; | ||
| 189 | |||
| 190 | range = find_range_array(count); | ||
| 191 | nr_range = 0; | ||
| 192 | |||
| 193 | addr = PFN_UP(addr); | ||
| 194 | limit = PFN_DOWN(limit); | ||
| 195 | |||
| 196 | for_each_memblock(memory, r) { | ||
| 197 | final_start = PFN_UP(r->base); | ||
| 198 | final_end = PFN_DOWN(r->base + r->size); | ||
| 199 | if (final_start >= final_end) | ||
| 200 | continue; | ||
| 201 | if (final_start >= limit || final_end <= addr) | ||
| 202 | continue; | ||
| 203 | |||
| 204 | nr_range = add_range(range, count, nr_range, final_start, final_end); | ||
| 205 | } | ||
| 206 | subtract_range(range, count, 0, addr); | ||
| 207 | subtract_range(range, count, limit, -1ULL); | ||
| 208 | |||
| 209 | /* Subtract memblock.reserved.region in range ? */ | ||
| 210 | if (!get_free) | ||
| 211 | goto sort_and_count_them; | ||
| 212 | for_each_memblock(reserved, r) { | ||
| 213 | final_start = PFN_DOWN(r->base); | ||
| 214 | final_end = PFN_UP(r->base + r->size); | ||
| 215 | if (final_start >= final_end) | ||
| 216 | continue; | ||
| 217 | if (final_start >= limit || final_end <= addr) | ||
| 218 | continue; | ||
| 219 | |||
| 220 | subtract_range(range, count, final_start, final_end); | ||
| 221 | } | ||
| 222 | |||
| 223 | sort_and_count_them: | ||
| 224 | nr_range = clean_sort_range(range, count); | ||
| 225 | |||
| 226 | free_size = 0; | ||
| 227 | for (i = 0; i < nr_range; i++) | ||
| 228 | free_size += range[i].end - range[i].start; | ||
| 229 | |||
| 230 | return free_size << PAGE_SHIFT; | ||
| 231 | } | ||
| 232 | |||
| 233 | u64 __init memblock_x86_free_memory_in_range(u64 addr, u64 limit) | ||
| 234 | { | ||
| 235 | return __memblock_x86_memory_in_range(addr, limit, true); | ||
| 236 | } | ||
| 237 | |||
| 238 | u64 __init memblock_x86_memory_in_range(u64 addr, u64 limit) | ||
| 239 | { | ||
| 240 | return __memblock_x86_memory_in_range(addr, limit, false); | ||
| 241 | } | ||
| 242 | |||
| 243 | void __init memblock_x86_reserve_range(u64 start, u64 end, char *name) | ||
| 244 | { | ||
| 245 | if (start == end) | ||
| 246 | return; | ||
| 247 | |||
| 248 | if (WARN_ONCE(start > end, "memblock_x86_reserve_range: wrong range [%#llx, %#llx)\n", start, end)) | ||
| 249 | return; | ||
| 250 | |||
| 251 | memblock_dbg(" memblock_x86_reserve_range: [%#010llx-%#010llx] %16s\n", start, end - 1, name); | ||
| 252 | |||
| 253 | memblock_reserve(start, end - start); | ||
| 254 | } | ||
| 255 | |||
| 256 | void __init memblock_x86_free_range(u64 start, u64 end) | ||
| 257 | { | ||
| 258 | if (start == end) | ||
| 259 | return; | ||
| 260 | |||
| 261 | if (WARN_ONCE(start > end, "memblock_x86_free_range: wrong range [%#llx, %#llx)\n", start, end)) | ||
| 262 | return; | ||
| 263 | |||
| 264 | memblock_dbg(" memblock_x86_free_range: [%#010llx-%#010llx]\n", start, end - 1); | ||
| 265 | |||
| 266 | memblock_free(start, end - start); | ||
| 267 | } | ||
| 268 | |||
| 269 | /* | ||
| 270 | * Need to call this function after memblock_x86_register_active_regions, | ||
| 271 | * so early_node_map[] is filled already. | ||
| 272 | */ | ||
| 273 | u64 __init memblock_x86_find_in_range_node(int nid, u64 start, u64 end, u64 size, u64 align) | ||
| 274 | { | ||
| 275 | u64 addr; | ||
| 276 | addr = find_memory_core_early(nid, size, align, start, end); | ||
| 277 | if (addr != MEMBLOCK_ERROR) | ||
| 278 | return addr; | ||
| 279 | |||
| 280 | /* Fallback, should already have start end within node range */ | ||
| 281 | return memblock_find_in_range(start, end, size, align); | ||
| 282 | } | ||
| 283 | |||
| 284 | /* | ||
| 285 | * Finds an active region in the address range from start_pfn to last_pfn and | ||
| 286 | * returns its range in ei_startpfn and ei_endpfn for the memblock entry. | ||
| 287 | */ | ||
| 288 | static int __init memblock_x86_find_active_region(const struct memblock_region *ei, | ||
| 289 | unsigned long start_pfn, | ||
| 290 | unsigned long last_pfn, | ||
| 291 | unsigned long *ei_startpfn, | ||
| 292 | unsigned long *ei_endpfn) | ||
| 293 | { | ||
| 294 | u64 align = PAGE_SIZE; | ||
| 295 | |||
| 296 | *ei_startpfn = round_up(ei->base, align) >> PAGE_SHIFT; | ||
| 297 | *ei_endpfn = round_down(ei->base + ei->size, align) >> PAGE_SHIFT; | ||
| 298 | |||
| 299 | /* Skip map entries smaller than a page */ | ||
| 300 | if (*ei_startpfn >= *ei_endpfn) | ||
| 301 | return 0; | ||
| 302 | |||
| 303 | /* Skip if map is outside the node */ | ||
| 304 | if (*ei_endpfn <= start_pfn || *ei_startpfn >= last_pfn) | ||
| 305 | return 0; | ||
| 306 | |||
| 307 | /* Check for overlaps */ | ||
| 308 | if (*ei_startpfn < start_pfn) | ||
| 309 | *ei_startpfn = start_pfn; | ||
| 310 | if (*ei_endpfn > last_pfn) | ||
| 311 | *ei_endpfn = last_pfn; | ||
| 312 | |||
| 313 | return 1; | ||
| 314 | } | ||
| 315 | |||
| 316 | /* Walk the memblock.memory map and register active regions within a node */ | ||
| 317 | void __init memblock_x86_register_active_regions(int nid, unsigned long start_pfn, | ||
| 318 | unsigned long last_pfn) | ||
| 319 | { | ||
| 320 | unsigned long ei_startpfn; | ||
| 321 | unsigned long ei_endpfn; | ||
| 322 | struct memblock_region *r; | ||
| 323 | |||
| 324 | for_each_memblock(memory, r) | ||
| 325 | if (memblock_x86_find_active_region(r, start_pfn, last_pfn, | ||
| 326 | &ei_startpfn, &ei_endpfn)) | ||
| 327 | add_active_range(nid, ei_startpfn, ei_endpfn); | ||
| 328 | } | ||
| 329 | |||
| 330 | /* | ||
| 331 | * Find the hole size (in bytes) in the memory range. | ||
| 332 | * @start: starting address of the memory range to scan | ||
| 333 | * @end: ending address of the memory range to scan | ||
| 334 | */ | ||
| 335 | u64 __init memblock_x86_hole_size(u64 start, u64 end) | ||
| 336 | { | ||
| 337 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
| 338 | unsigned long last_pfn = end >> PAGE_SHIFT; | ||
| 339 | unsigned long ei_startpfn, ei_endpfn, ram = 0; | ||
| 340 | struct memblock_region *r; | ||
| 341 | |||
| 342 | for_each_memblock(memory, r) | ||
| 343 | if (memblock_x86_find_active_region(r, start_pfn, last_pfn, | ||
| 344 | &ei_startpfn, &ei_endpfn)) | ||
| 345 | ram += ei_endpfn - ei_startpfn; | ||
| 346 | |||
| 347 | return end - start - ((u64)ram << PAGE_SHIFT); | ||
| 348 | } | ||
diff --git a/arch/x86/oprofile/nmi_timer_int.c b/arch/x86/oprofile/nmi_timer_int.c new file mode 100644 index 00000000000..720bf5a53c5 --- /dev/null +++ b/arch/x86/oprofile/nmi_timer_int.c | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /** | ||
| 2 | * @file nmi_timer_int.c | ||
| 3 | * | ||
| 4 | * @remark Copyright 2003 OProfile authors | ||
| 5 | * @remark Read the file COPYING | ||
| 6 | * | ||
| 7 | * @author Zwane Mwaikambo <zwane@linuxpower.ca> | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/smp.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/oprofile.h> | ||
| 14 | #include <linux/rcupdate.h> | ||
| 15 | #include <linux/kdebug.h> | ||
| 16 | |||
| 17 | #include <asm/nmi.h> | ||
| 18 | #include <asm/apic.h> | ||
| 19 | #include <asm/ptrace.h> | ||
| 20 | |||
| 21 | static int profile_timer_exceptions_notify(struct notifier_block *self, | ||
| 22 | unsigned long val, void *data) | ||
| 23 | { | ||
| 24 | struct die_args *args = (struct die_args *)data; | ||
| 25 | int ret = NOTIFY_DONE; | ||
| 26 | |||
| 27 | switch (val) { | ||
| 28 | case DIE_NMI: | ||
| 29 | oprofile_add_sample(args->regs, 0); | ||
| 30 | ret = NOTIFY_STOP; | ||
| 31 | break; | ||
| 32 | default: | ||
| 33 | break; | ||
| 34 | } | ||
| 35 | return ret; | ||
| 36 | } | ||
| 37 | |||
| 38 | static struct notifier_block profile_timer_exceptions_nb = { | ||
| 39 | .notifier_call = profile_timer_exceptions_notify, | ||
| 40 | .next = NULL, | ||
| 41 | .priority = NMI_LOW_PRIOR, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static int timer_start(void) | ||
| 45 | { | ||
| 46 | if (register_die_notifier(&profile_timer_exceptions_nb)) | ||
| 47 | return 1; | ||
| 48 | return 0; | ||
| 49 | } | ||
| 50 | |||
| 51 | |||
| 52 | static void timer_stop(void) | ||
| 53 | { | ||
| 54 | unregister_die_notifier(&profile_timer_exceptions_nb); | ||
| 55 | synchronize_sched(); /* Allow already-started NMIs to complete. */ | ||
| 56 | } | ||
| 57 | |||
| 58 | |||
| 59 | int __init op_nmi_timer_init(struct oprofile_operations *ops) | ||
| 60 | { | ||
| 61 | ops->start = timer_start; | ||
| 62 | ops->stop = timer_stop; | ||
| 63 | ops->cpu_type = "timer"; | ||
| 64 | printk(KERN_INFO "oprofile: using NMI timer interrupt.\n"); | ||
| 65 | return 0; | ||
| 66 | } | ||
diff --git a/arch/x86/platform/mrst/pmu.c b/arch/x86/platform/mrst/pmu.c new file mode 100644 index 00000000000..9281da7d91b --- /dev/null +++ b/arch/x86/platform/mrst/pmu.c | |||
| @@ -0,0 +1,817 @@ | |||
| 1 | /* | ||
| 2 | * mrst/pmu.c - driver for MRST Power Management Unit | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011, Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License along with | ||
| 16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/cpuidle.h> | ||
| 21 | #include <linux/debugfs.h> | ||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/pci.h> | ||
| 26 | #include <linux/seq_file.h> | ||
| 27 | #include <linux/sfi.h> | ||
| 28 | #include <asm/intel_scu_ipc.h> | ||
| 29 | #include "pmu.h" | ||
| 30 | |||
| 31 | #define IPCMSG_FW_REVISION 0xF4 | ||
| 32 | |||
| 33 | struct mrst_device { | ||
| 34 | u16 pci_dev_num; /* DEBUG only */ | ||
| 35 | u16 lss; | ||
| 36 | u16 latest_request; | ||
| 37 | unsigned int pci_state_counts[PCI_D3cold + 1]; /* DEBUG only */ | ||
| 38 | }; | ||
| 39 | |||
| 40 | /* | ||
| 41 | * comlete list of MRST PCI devices | ||
| 42 | */ | ||
| 43 | static struct mrst_device mrst_devs[] = { | ||
| 44 | /* 0 */ { 0x0800, LSS_SPI0 }, /* Moorestown SPI Ctrl 0 */ | ||
| 45 | /* 1 */ { 0x0801, LSS_SPI1 }, /* Moorestown SPI Ctrl 1 */ | ||
| 46 | /* 2 */ { 0x0802, LSS_I2C0 }, /* Moorestown I2C 0 */ | ||
| 47 | /* 3 */ { 0x0803, LSS_I2C1 }, /* Moorestown I2C 1 */ | ||
| 48 | /* 4 */ { 0x0804, LSS_I2C2 }, /* Moorestown I2C 2 */ | ||
| 49 | /* 5 */ { 0x0805, LSS_KBD }, /* Moorestown Keyboard Ctrl */ | ||
| 50 | /* 6 */ { 0x0806, LSS_USB_HC }, /* Moorestown USB Ctrl */ | ||
| 51 | /* 7 */ { 0x0807, LSS_SD_HC0 }, /* Moorestown SD Host Ctrl 0 */ | ||
| 52 | /* 8 */ { 0x0808, LSS_SD_HC1 }, /* Moorestown SD Host Ctrl 1 */ | ||
| 53 | /* 9 */ { 0x0809, LSS_NAND }, /* Moorestown NAND Ctrl */ | ||
| 54 | /* 10 */ { 0x080a, LSS_AUDIO }, /* Moorestown Audio Ctrl */ | ||
| 55 | /* 11 */ { 0x080b, LSS_IMAGING }, /* Moorestown ISP */ | ||
| 56 | /* 12 */ { 0x080c, LSS_SECURITY }, /* Moorestown Security Controller */ | ||
| 57 | /* 13 */ { 0x080d, LSS_DISPLAY }, /* Moorestown External Displays */ | ||
| 58 | /* 14 */ { 0x080e, 0 }, /* Moorestown SCU IPC */ | ||
| 59 | /* 15 */ { 0x080f, LSS_GPIO }, /* Moorestown GPIO Controller */ | ||
| 60 | /* 16 */ { 0x0810, 0 }, /* Moorestown Power Management Unit */ | ||
| 61 | /* 17 */ { 0x0811, LSS_USB_OTG }, /* Moorestown OTG Ctrl */ | ||
| 62 | /* 18 */ { 0x0812, LSS_SPI2 }, /* Moorestown SPI Ctrl 2 */ | ||
| 63 | /* 19 */ { 0x0813, 0 }, /* Moorestown SC DMA */ | ||
| 64 | /* 20 */ { 0x0814, LSS_AUDIO_LPE }, /* Moorestown LPE DMA */ | ||
| 65 | /* 21 */ { 0x0815, LSS_AUDIO_SSP }, /* Moorestown SSP0 */ | ||
| 66 | |||
| 67 | /* 22 */ { 0x084F, LSS_SD_HC2 }, /* Moorestown SD Host Ctrl 2 */ | ||
| 68 | |||
| 69 | /* 23 */ { 0x4102, 0 }, /* Lincroft */ | ||
| 70 | /* 24 */ { 0x4110, 0 }, /* Lincroft */ | ||
| 71 | }; | ||
| 72 | |||
| 73 | /* n.b. We ignore PCI-id 0x815 in LSS9 b/c MeeGo has no driver for it */ | ||
| 74 | static u16 mrst_lss9_pci_ids[] = {0x080a, 0x0814, 0}; | ||
| 75 | static u16 mrst_lss10_pci_ids[] = {0x0800, 0x0801, 0x0802, 0x0803, | ||
| 76 | 0x0804, 0x0805, 0x080f, 0}; | ||
| 77 | |||
| 78 | /* handle concurrent SMP invokations of pmu_pci_set_power_state() */ | ||
| 79 | static spinlock_t mrst_pmu_power_state_lock; | ||
| 80 | |||
| 81 | static unsigned int wake_counters[MRST_NUM_LSS]; /* DEBUG only */ | ||
| 82 | static unsigned int pmu_irq_stats[INT_INVALID + 1]; /* DEBUG only */ | ||
| 83 | |||
| 84 | static int graphics_is_off; | ||
| 85 | static int lss_s0i3_enabled; | ||
| 86 | static bool mrst_pmu_s0i3_enable; | ||
| 87 | |||
| 88 | /* debug counters */ | ||
| 89 | static u32 pmu_wait_ready_calls; | ||
| 90 | static u32 pmu_wait_ready_udelays; | ||
| 91 | static u32 pmu_wait_ready_udelays_max; | ||
| 92 | static u32 pmu_wait_done_calls; | ||
| 93 | static u32 pmu_wait_done_udelays; | ||
| 94 | static u32 pmu_wait_done_udelays_max; | ||
| 95 | static u32 pmu_set_power_state_entry; | ||
| 96 | static u32 pmu_set_power_state_send_cmd; | ||
| 97 | |||
| 98 | static struct mrst_device *pci_id_2_mrst_dev(u16 pci_dev_num) | ||
| 99 | { | ||
| 100 | int index = 0; | ||
| 101 | |||
| 102 | if ((pci_dev_num >= 0x0800) && (pci_dev_num <= 0x815)) | ||
| 103 | index = pci_dev_num - 0x800; | ||
| 104 | else if (pci_dev_num == 0x084F) | ||
| 105 | index = 22; | ||
| 106 | else if (pci_dev_num == 0x4102) | ||
| 107 | index = 23; | ||
| 108 | else if (pci_dev_num == 0x4110) | ||
| 109 | index = 24; | ||
| 110 | |||
| 111 | if (pci_dev_num != mrst_devs[index].pci_dev_num) { | ||
| 112 | WARN_ONCE(1, FW_BUG "Unknown PCI device 0x%04X\n", pci_dev_num); | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | return &mrst_devs[index]; | ||
| 117 | } | ||
| 118 | |||
| 119 | /** | ||
| 120 | * mrst_pmu_validate_cstates | ||
| 121 | * @dev: cpuidle_device | ||
| 122 | * | ||
| 123 | * Certain states are not appropriate for governor to pick in some cases. | ||
| 124 | * This function will be called as cpuidle_device's prepare callback and | ||
| 125 | * thus tells governor to ignore such states when selecting the next state | ||
| 126 | * to enter. | ||
| 127 | */ | ||
| 128 | |||
| 129 | #define IDLE_STATE4_IS_C6 4 | ||
| 130 | #define IDLE_STATE5_IS_S0I3 5 | ||
| 131 | |||
| 132 | int mrst_pmu_invalid_cstates(void) | ||
| 133 | { | ||
| 134 | int cpu = smp_processor_id(); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * Demote to C4 if the PMU is busy. | ||
| 138 | * Since LSS changes leave the busy bit clear... | ||
| 139 | * busy means either the PMU is waiting for an ACK-C6 that | ||
| 140 | * isn't coming due to an MWAIT that returned immediately; | ||
| 141 | * or we returned from S0i3 successfully, and the PMU | ||
| 142 | * is not done sending us interrupts. | ||
| 143 | */ | ||
| 144 | if (pmu_read_busy_status()) | ||
| 145 | return 1 << IDLE_STATE4_IS_C6 | 1 << IDLE_STATE5_IS_S0I3; | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Disallow S0i3 if: PMU is not initialized, or CPU1 is active, | ||
| 149 | * or if device LSS is insufficient, or the GPU is active, | ||
| 150 | * or if it has been explicitly disabled. | ||
| 151 | */ | ||
| 152 | if (!pmu_reg || !cpumask_equal(cpu_online_mask, cpumask_of(cpu)) || | ||
| 153 | !lss_s0i3_enabled || !graphics_is_off || !mrst_pmu_s0i3_enable) | ||
| 154 | return 1 << IDLE_STATE5_IS_S0I3; | ||
| 155 | else | ||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | /* | ||
| 160 | * pmu_update_wake_counters(): read PM_WKS, update wake_counters[] | ||
| 161 | * DEBUG only. | ||
| 162 | */ | ||
| 163 | static void pmu_update_wake_counters(void) | ||
| 164 | { | ||
| 165 | int lss; | ||
| 166 | u32 wake_status; | ||
| 167 | |||
| 168 | wake_status = pmu_read_wks(); | ||
| 169 | |||
| 170 | for (lss = 0; lss < MRST_NUM_LSS; ++lss) { | ||
| 171 | if (wake_status & (1 << lss)) | ||
| 172 | wake_counters[lss]++; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | int mrst_pmu_s0i3_entry(void) | ||
| 177 | { | ||
| 178 | int status; | ||
| 179 | |||
| 180 | /* Clear any possible error conditions */ | ||
| 181 | pmu_write_ics(0x300); | ||
| 182 | |||
| 183 | /* set wake control to current D-states */ | ||
| 184 | pmu_write_wssc(S0I3_SSS_TARGET); | ||
| 185 | |||
| 186 | status = mrst_s0i3_entry(PM_S0I3_COMMAND, &pmu_reg->pm_cmd); | ||
| 187 | pmu_update_wake_counters(); | ||
| 188 | return status; | ||
| 189 | } | ||
| 190 | |||
| 191 | /* poll for maximum of 5ms for busy bit to clear */ | ||
| 192 | static int pmu_wait_ready(void) | ||
| 193 | { | ||
| 194 | int udelays; | ||
| 195 | |||
| 196 | pmu_wait_ready_calls++; | ||
| 197 | |||
| 198 | for (udelays = 0; udelays < 500; ++udelays) { | ||
| 199 | if (udelays > pmu_wait_ready_udelays_max) | ||
| 200 | pmu_wait_ready_udelays_max = udelays; | ||
| 201 | |||
| 202 | if (pmu_read_busy_status() == 0) | ||
| 203 | return 0; | ||
| 204 | |||
| 205 | udelay(10); | ||
| 206 | pmu_wait_ready_udelays++; | ||
| 207 | } | ||
| 208 | |||
| 209 | /* | ||
| 210 | * if this fires, observe | ||
| 211 | * /sys/kernel/debug/mrst_pmu_wait_ready_calls | ||
| 212 | * /sys/kernel/debug/mrst_pmu_wait_ready_udelays | ||
| 213 | */ | ||
| 214 | WARN_ONCE(1, "SCU not ready for 5ms"); | ||
| 215 | return -EBUSY; | ||
| 216 | } | ||
| 217 | /* poll for maximum of 50ms us for busy bit to clear */ | ||
| 218 | static int pmu_wait_done(void) | ||
| 219 | { | ||
| 220 | int udelays; | ||
| 221 | |||
| 222 | pmu_wait_done_calls++; | ||
| 223 | |||
| 224 | for (udelays = 0; udelays < 500; ++udelays) { | ||
| 225 | if (udelays > pmu_wait_done_udelays_max) | ||
| 226 | pmu_wait_done_udelays_max = udelays; | ||
| 227 | |||
| 228 | if (pmu_read_busy_status() == 0) | ||
| 229 | return 0; | ||
| 230 | |||
| 231 | udelay(100); | ||
| 232 | pmu_wait_done_udelays++; | ||
| 233 | } | ||
| 234 | |||
| 235 | /* | ||
| 236 | * if this fires, observe | ||
| 237 | * /sys/kernel/debug/mrst_pmu_wait_done_calls | ||
| 238 | * /sys/kernel/debug/mrst_pmu_wait_done_udelays | ||
| 239 | */ | ||
| 240 | WARN_ONCE(1, "SCU not done for 50ms"); | ||
| 241 | return -EBUSY; | ||
| 242 | } | ||
| 243 | |||
| 244 | u32 mrst_pmu_msi_is_disabled(void) | ||
| 245 | { | ||
| 246 | return pmu_msi_is_disabled(); | ||
| 247 | } | ||
| 248 | |||
| 249 | void mrst_pmu_enable_msi(void) | ||
| 250 | { | ||
| 251 | pmu_msi_enable(); | ||
| 252 | } | ||
| 253 | |||
| 254 | /** | ||
| 255 | * pmu_irq - pmu driver interrupt handler | ||
| 256 | * Context: interrupt context | ||
| 257 | */ | ||
| 258 | static irqreturn_t pmu_irq(int irq, void *dummy) | ||
| 259 | { | ||
| 260 | union pmu_pm_ics pmu_ics; | ||
| 261 | |||
| 262 | pmu_ics.value = pmu_read_ics(); | ||
| 263 | |||
| 264 | if (!pmu_ics.bits.pending) | ||
| 265 | return IRQ_NONE; | ||
| 266 | |||
| 267 | switch (pmu_ics.bits.cause) { | ||
| 268 | case INT_SPURIOUS: | ||
| 269 | case INT_CMD_DONE: | ||
| 270 | case INT_CMD_ERR: | ||
| 271 | case INT_WAKE_RX: | ||
| 272 | case INT_SS_ERROR: | ||
| 273 | case INT_S0IX_MISS: | ||
| 274 | case INT_NO_ACKC6: | ||
| 275 | pmu_irq_stats[pmu_ics.bits.cause]++; | ||
| 276 | break; | ||
| 277 | default: | ||
| 278 | pmu_irq_stats[INT_INVALID]++; | ||
| 279 | } | ||
| 280 | |||
| 281 | pmu_write_ics(pmu_ics.value); /* Clear pending interrupt */ | ||
| 282 | |||
| 283 | return IRQ_HANDLED; | ||
| 284 | } | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Translate PCI power management to MRST LSS D-states | ||
| 288 | */ | ||
| 289 | static int pci_2_mrst_state(int lss, pci_power_t pci_state) | ||
| 290 | { | ||
| 291 | switch (pci_state) { | ||
| 292 | case PCI_D0: | ||
| 293 | if (SSMSK(D0i1, lss) & D0I1_ACG_SSS_TARGET) | ||
| 294 | return D0i1; | ||
| 295 | else | ||
| 296 | return D0; | ||
| 297 | case PCI_D1: | ||
| 298 | return D0i1; | ||
| 299 | case PCI_D2: | ||
| 300 | return D0i2; | ||
| 301 | case PCI_D3hot: | ||
| 302 | case PCI_D3cold: | ||
| 303 | return D0i3; | ||
| 304 | default: | ||
| 305 | WARN(1, "pci_state %d\n", pci_state); | ||
| 306 | return 0; | ||
| 307 | } | ||
| 308 | } | ||
| 309 | |||
| 310 | static int pmu_issue_command(u32 pm_ssc) | ||
| 311 | { | ||
| 312 | union pmu_pm_set_cfg_cmd_t command; | ||
| 313 | |||
| 314 | if (pmu_read_busy_status()) { | ||
| 315 | pr_debug("pmu is busy, Operation not permitted\n"); | ||
| 316 | return -1; | ||
| 317 | } | ||
| 318 | |||
| 319 | /* | ||
| 320 | * enable interrupts in PMU so that interrupts are | ||
| 321 | * propagated when ioc bit for a particular set | ||
| 322 | * command is set | ||
| 323 | */ | ||
| 324 | |||
| 325 | pmu_irq_enable(); | ||
| 326 | |||
| 327 | /* Configure the sub systems for pmu2 */ | ||
| 328 | |||
| 329 | pmu_write_ssc(pm_ssc); | ||
| 330 | |||
| 331 | /* | ||
| 332 | * Send the set config command for pmu its configured | ||
| 333 | * for mode CM_IMMEDIATE & hence with No Trigger | ||
| 334 | */ | ||
| 335 | |||
| 336 | command.pmu2_params.d_param.cfg_mode = CM_IMMEDIATE; | ||
| 337 | command.pmu2_params.d_param.cfg_delay = 0; | ||
| 338 | command.pmu2_params.d_param.rsvd = 0; | ||
| 339 | |||
| 340 | /* construct the command to send SET_CFG to particular PMU */ | ||
| 341 | command.pmu2_params.d_param.cmd = SET_CFG_CMD; | ||
| 342 | command.pmu2_params.d_param.ioc = 0; | ||
| 343 | command.pmu2_params.d_param.mode_id = 0; | ||
| 344 | command.pmu2_params.d_param.sys_state = SYS_STATE_S0I0; | ||
| 345 | |||
| 346 | /* write the value of PM_CMD into particular PMU */ | ||
| 347 | pr_debug("pmu command being written %x\n", | ||
| 348 | command.pmu_pm_set_cfg_cmd_value); | ||
| 349 | |||
| 350 | pmu_write_cmd(command.pmu_pm_set_cfg_cmd_value); | ||
| 351 | |||
| 352 | return 0; | ||
| 353 | } | ||
| 354 | |||
| 355 | static u16 pmu_min_lss_pci_req(u16 *ids, u16 pci_state) | ||
| 356 | { | ||
| 357 | u16 existing_request; | ||
| 358 | int i; | ||
| 359 | |||
| 360 | for (i = 0; ids[i]; ++i) { | ||
| 361 | struct mrst_device *mrst_dev; | ||
| 362 | |||
| 363 | mrst_dev = pci_id_2_mrst_dev(ids[i]); | ||
| 364 | if (unlikely(!mrst_dev)) | ||
| 365 | continue; | ||
| 366 | |||
| 367 | existing_request = mrst_dev->latest_request; | ||
| 368 | if (existing_request < pci_state) | ||
| 369 | pci_state = existing_request; | ||
| 370 | } | ||
| 371 | return pci_state; | ||
| 372 | } | ||
| 373 | |||
| 374 | /** | ||
| 375 | * pmu_pci_set_power_state - Callback function is used by all the PCI devices | ||
| 376 | * for a platform specific device power on/shutdown. | ||
| 377 | */ | ||
| 378 | |||
| 379 | int pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t pci_state) | ||
| 380 | { | ||
| 381 | u32 old_sss, new_sss; | ||
| 382 | int status = 0; | ||
| 383 | struct mrst_device *mrst_dev; | ||
| 384 | |||
| 385 | pmu_set_power_state_entry++; | ||
| 386 | |||
| 387 | BUG_ON(pdev->vendor != PCI_VENDOR_ID_INTEL); | ||
| 388 | BUG_ON(pci_state < PCI_D0 || pci_state > PCI_D3cold); | ||
| 389 | |||
| 390 | mrst_dev = pci_id_2_mrst_dev(pdev->device); | ||
| 391 | if (unlikely(!mrst_dev)) | ||
| 392 | return -ENODEV; | ||
| 393 | |||
| 394 | mrst_dev->pci_state_counts[pci_state]++; /* count invocations */ | ||
| 395 | |||
| 396 | /* PMU driver calls self as part of PCI initialization, ignore */ | ||
| 397 | if (pdev->device == PCI_DEV_ID_MRST_PMU) | ||
| 398 | return 0; | ||
| 399 | |||
| 400 | BUG_ON(!pmu_reg); /* SW bug if called before initialized */ | ||
| 401 | |||
| 402 | spin_lock(&mrst_pmu_power_state_lock); | ||
| 403 | |||
| 404 | if (pdev->d3_delay) { | ||
| 405 | dev_dbg(&pdev->dev, "d3_delay %d, should be 0\n", | ||
| 406 | pdev->d3_delay); | ||
| 407 | pdev->d3_delay = 0; | ||
| 408 | } | ||
| 409 | /* | ||
| 410 | * If Lincroft graphics, simply remember state | ||
| 411 | */ | ||
| 412 | if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY | ||
| 413 | && !((pdev->class & PCI_SUB_CLASS_MASK) >> 8)) { | ||
| 414 | if (pci_state == PCI_D0) | ||
| 415 | graphics_is_off = 0; | ||
| 416 | else | ||
| 417 | graphics_is_off = 1; | ||
| 418 | goto ret; | ||
| 419 | } | ||
| 420 | |||
| 421 | if (!mrst_dev->lss) | ||
| 422 | goto ret; /* device with no LSS */ | ||
| 423 | |||
| 424 | if (mrst_dev->latest_request == pci_state) | ||
| 425 | goto ret; /* no change */ | ||
| 426 | |||
| 427 | mrst_dev->latest_request = pci_state; /* record latest request */ | ||
| 428 | |||
| 429 | /* | ||
| 430 | * LSS9 and LSS10 contain multiple PCI devices. | ||
| 431 | * Use the lowest numbered (highest power) state in the LSS | ||
| 432 | */ | ||
| 433 | if (mrst_dev->lss == 9) | ||
| 434 | pci_state = pmu_min_lss_pci_req(mrst_lss9_pci_ids, pci_state); | ||
| 435 | else if (mrst_dev->lss == 10) | ||
| 436 | pci_state = pmu_min_lss_pci_req(mrst_lss10_pci_ids, pci_state); | ||
| 437 | |||
| 438 | status = pmu_wait_ready(); | ||
| 439 | if (status) | ||
| 440 | goto ret; | ||
| 441 | |||
| 442 | old_sss = pmu_read_sss(); | ||
| 443 | new_sss = old_sss & ~SSMSK(3, mrst_dev->lss); | ||
| 444 | new_sss |= SSMSK(pci_2_mrst_state(mrst_dev->lss, pci_state), | ||
| 445 | mrst_dev->lss); | ||
| 446 | |||
| 447 | if (new_sss == old_sss) | ||
| 448 | goto ret; /* nothing to do */ | ||
| 449 | |||
| 450 | pmu_set_power_state_send_cmd++; | ||
| 451 | |||
| 452 | status = pmu_issue_command(new_sss); | ||
| 453 | |||
| 454 | if (unlikely(status != 0)) { | ||
| 455 | dev_err(&pdev->dev, "Failed to Issue a PM command\n"); | ||
| 456 | goto ret; | ||
| 457 | } | ||
| 458 | |||
| 459 | if (pmu_wait_done()) | ||
| 460 | goto ret; | ||
| 461 | |||
| 462 | lss_s0i3_enabled = | ||
| 463 | ((pmu_read_sss() & S0I3_SSS_TARGET) == S0I3_SSS_TARGET); | ||
| 464 | ret: | ||
| 465 | spin_unlock(&mrst_pmu_power_state_lock); | ||
| 466 | return status; | ||
| 467 | } | ||
| 468 | |||
| 469 | #ifdef CONFIG_DEBUG_FS | ||
| 470 | static char *d0ix_names[] = {"D0", "D0i1", "D0i2", "D0i3"}; | ||
| 471 | |||
| 472 | static inline const char *d0ix_name(int state) | ||
| 473 | { | ||
| 474 | return d0ix_names[(int) state]; | ||
| 475 | } | ||
| 476 | |||
| 477 | static int debug_mrst_pmu_show(struct seq_file *s, void *unused) | ||
| 478 | { | ||
| 479 | struct pci_dev *pdev = NULL; | ||
| 480 | u32 cur_pmsss; | ||
| 481 | int lss; | ||
| 482 | |||
| 483 | seq_printf(s, "0x%08X D0I1_ACG_SSS_TARGET\n", D0I1_ACG_SSS_TARGET); | ||
| 484 | |||
| 485 | cur_pmsss = pmu_read_sss(); | ||
| 486 | |||
| 487 | seq_printf(s, "0x%08X S0I3_SSS_TARGET\n", S0I3_SSS_TARGET); | ||
| 488 | |||
| 489 | seq_printf(s, "0x%08X Current SSS ", cur_pmsss); | ||
| 490 | seq_printf(s, lss_s0i3_enabled ? "\n" : "[BLOCKS s0i3]\n"); | ||
| 491 | |||
| 492 | if (cpumask_equal(cpu_online_mask, cpumask_of(0))) | ||
| 493 | seq_printf(s, "cpu0 is only cpu online\n"); | ||
| 494 | else | ||
| 495 | seq_printf(s, "cpu0 is NOT only cpu online [BLOCKS S0i3]\n"); | ||
| 496 | |||
| 497 | seq_printf(s, "GFX: %s\n", graphics_is_off ? "" : "[BLOCKS s0i3]"); | ||
| 498 | |||
| 499 | |||
| 500 | for_each_pci_dev(pdev) { | ||
| 501 | int pos; | ||
| 502 | u16 pmcsr; | ||
| 503 | struct mrst_device *mrst_dev; | ||
| 504 | int i; | ||
| 505 | |||
| 506 | mrst_dev = pci_id_2_mrst_dev(pdev->device); | ||
| 507 | |||
| 508 | seq_printf(s, "%s %04x/%04X %-16.16s ", | ||
| 509 | dev_name(&pdev->dev), | ||
| 510 | pdev->vendor, pdev->device, | ||
| 511 | dev_driver_string(&pdev->dev)); | ||
| 512 | |||
| 513 | if (unlikely (!mrst_dev)) { | ||
| 514 | seq_printf(s, " UNKNOWN\n"); | ||
| 515 | continue; | ||
| 516 | } | ||
| 517 | |||
| 518 | if (mrst_dev->lss) | ||
| 519 | seq_printf(s, "LSS %2d %-4s ", mrst_dev->lss, | ||
| 520 | d0ix_name(((cur_pmsss >> | ||
| 521 | (mrst_dev->lss * 2)) & 0x3))); | ||
| 522 | else | ||
| 523 | seq_printf(s, " "); | ||
| 524 | |||
| 525 | /* PCI PM config space setting */ | ||
| 526 | pos = pci_find_capability(pdev, PCI_CAP_ID_PM); | ||
| 527 | if (pos != 0) { | ||
| 528 | pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); | ||
| 529 | seq_printf(s, "PCI-%-4s", | ||
| 530 | pci_power_name(pmcsr & PCI_PM_CTRL_STATE_MASK)); | ||
| 531 | } else { | ||
| 532 | seq_printf(s, " "); | ||
| 533 | } | ||
| 534 | |||
| 535 | seq_printf(s, " %s ", pci_power_name(mrst_dev->latest_request)); | ||
| 536 | for (i = 0; i <= PCI_D3cold; ++i) | ||
| 537 | seq_printf(s, "%d ", mrst_dev->pci_state_counts[i]); | ||
| 538 | |||
| 539 | if (mrst_dev->lss) { | ||
| 540 | unsigned int lssmask; | ||
| 541 | |||
| 542 | lssmask = SSMSK(D0i3, mrst_dev->lss); | ||
| 543 | |||
| 544 | if ((lssmask & S0I3_SSS_TARGET) && | ||
| 545 | ((lssmask & cur_pmsss) != | ||
| 546 | (lssmask & S0I3_SSS_TARGET))) | ||
| 547 | seq_printf(s , "[BLOCKS s0i3]"); | ||
| 548 | } | ||
| 549 | |||
| 550 | seq_printf(s, "\n"); | ||
| 551 | } | ||
| 552 | seq_printf(s, "Wake Counters:\n"); | ||
| 553 | for (lss = 0; lss < MRST_NUM_LSS; ++lss) | ||
| 554 | seq_printf(s, "LSS%d %d\n", lss, wake_counters[lss]); | ||
| 555 | |||
| 556 | seq_printf(s, "Interrupt Counters:\n"); | ||
| 557 | seq_printf(s, | ||
| 558 | "INT_SPURIOUS \t%8u\n" "INT_CMD_DONE \t%8u\n" | ||
| 559 | "INT_CMD_ERR \t%8u\n" "INT_WAKE_RX \t%8u\n" | ||
| 560 | "INT_SS_ERROR \t%8u\n" "INT_S0IX_MISS\t%8u\n" | ||
| 561 | "INT_NO_ACKC6 \t%8u\n" "INT_INVALID \t%8u\n", | ||
| 562 | pmu_irq_stats[INT_SPURIOUS], pmu_irq_stats[INT_CMD_DONE], | ||
| 563 | pmu_irq_stats[INT_CMD_ERR], pmu_irq_stats[INT_WAKE_RX], | ||
| 564 | pmu_irq_stats[INT_SS_ERROR], pmu_irq_stats[INT_S0IX_MISS], | ||
| 565 | pmu_irq_stats[INT_NO_ACKC6], pmu_irq_stats[INT_INVALID]); | ||
| 566 | |||
| 567 | seq_printf(s, "mrst_pmu_wait_ready_calls %8d\n", | ||
| 568 | pmu_wait_ready_calls); | ||
| 569 | seq_printf(s, "mrst_pmu_wait_ready_udelays %8d\n", | ||
| 570 | pmu_wait_ready_udelays); | ||
| 571 | seq_printf(s, "mrst_pmu_wait_ready_udelays_max %8d\n", | ||
| 572 | pmu_wait_ready_udelays_max); | ||
| 573 | seq_printf(s, "mrst_pmu_wait_done_calls %8d\n", | ||
| 574 | pmu_wait_done_calls); | ||
| 575 | seq_printf(s, "mrst_pmu_wait_done_udelays %8d\n", | ||
| 576 | pmu_wait_done_udelays); | ||
| 577 | seq_printf(s, "mrst_pmu_wait_done_udelays_max %8d\n", | ||
| 578 | pmu_wait_done_udelays_max); | ||
| 579 | seq_printf(s, "mrst_pmu_set_power_state_entry %8d\n", | ||
| 580 | pmu_set_power_state_entry); | ||
| 581 | seq_printf(s, "mrst_pmu_set_power_state_send_cmd %8d\n", | ||
| 582 | pmu_set_power_state_send_cmd); | ||
| 583 | seq_printf(s, "SCU busy: %d\n", pmu_read_busy_status()); | ||
| 584 | |||
| 585 | return 0; | ||
| 586 | } | ||
| 587 | |||
| 588 | static int debug_mrst_pmu_open(struct inode *inode, struct file *file) | ||
| 589 | { | ||
| 590 | return single_open(file, debug_mrst_pmu_show, NULL); | ||
| 591 | } | ||
| 592 | |||
| 593 | static const struct file_operations devices_state_operations = { | ||
| 594 | .open = debug_mrst_pmu_open, | ||
| 595 | .read = seq_read, | ||
| 596 | .llseek = seq_lseek, | ||
| 597 | .release = single_release, | ||
| 598 | }; | ||
| 599 | #endif /* DEBUG_FS */ | ||
| 600 | |||
| 601 | /* | ||
| 602 | * Validate SCU PCI shim PCI vendor capability byte | ||
| 603 | * against LSS hard-coded in mrst_devs[] above. | ||
| 604 | * DEBUG only. | ||
| 605 | */ | ||
| 606 | static void pmu_scu_firmware_debug(void) | ||
| 607 | { | ||
| 608 | struct pci_dev *pdev = NULL; | ||
| 609 | |||
| 610 | for_each_pci_dev(pdev) { | ||
| 611 | struct mrst_device *mrst_dev; | ||
| 612 | u8 pci_config_lss; | ||
| 613 | int pos; | ||
| 614 | |||
| 615 | mrst_dev = pci_id_2_mrst_dev(pdev->device); | ||
| 616 | if (unlikely(!mrst_dev)) { | ||
| 617 | printk(KERN_ERR FW_BUG "pmu: Unknown " | ||
| 618 | "PCI device 0x%04X\n", pdev->device); | ||
| 619 | continue; | ||
| 620 | } | ||
| 621 | |||
| 622 | if (mrst_dev->lss == 0) | ||
| 623 | continue; /* no LSS in our table */ | ||
| 624 | |||
| 625 | pos = pci_find_capability(pdev, PCI_CAP_ID_VNDR); | ||
| 626 | if (!pos != 0) { | ||
| 627 | printk(KERN_ERR FW_BUG "pmu: 0x%04X " | ||
| 628 | "missing PCI Vendor Capability\n", | ||
| 629 | pdev->device); | ||
| 630 | continue; | ||
| 631 | } | ||
| 632 | pci_read_config_byte(pdev, pos + 4, &pci_config_lss); | ||
| 633 | if (!(pci_config_lss & PCI_VENDOR_CAP_LOG_SS_MASK)) { | ||
| 634 | printk(KERN_ERR FW_BUG "pmu: 0x%04X " | ||
| 635 | "invalid PCI Vendor Capability 0x%x " | ||
| 636 | " expected LSS 0x%X\n", | ||
| 637 | pdev->device, pci_config_lss, mrst_dev->lss); | ||
| 638 | continue; | ||
| 639 | } | ||
| 640 | pci_config_lss &= PCI_VENDOR_CAP_LOG_ID_MASK; | ||
| 641 | |||
| 642 | if (mrst_dev->lss == pci_config_lss) | ||
| 643 | continue; | ||
| 644 | |||
| 645 | printk(KERN_ERR FW_BUG "pmu: 0x%04X LSS = %d, expected %d\n", | ||
| 646 | pdev->device, pci_config_lss, mrst_dev->lss); | ||
| 647 | } | ||
| 648 | } | ||
| 649 | |||
| 650 | /** | ||
| 651 | * pmu_probe | ||
| 652 | */ | ||
| 653 | static int __devinit pmu_probe(struct pci_dev *pdev, | ||
| 654 | const struct pci_device_id *pci_id) | ||
| 655 | { | ||
| 656 | int ret; | ||
| 657 | struct mrst_pmu_reg *pmu; | ||
| 658 | |||
| 659 | /* Init the device */ | ||
| 660 | ret = pci_enable_device(pdev); | ||
| 661 | if (ret) { | ||
| 662 | dev_err(&pdev->dev, "Unable to Enable PCI device\n"); | ||
| 663 | return ret; | ||
| 664 | } | ||
| 665 | |||
| 666 | ret = pci_request_regions(pdev, MRST_PMU_DRV_NAME); | ||
| 667 | if (ret < 0) { | ||
| 668 | dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n"); | ||
| 669 | goto out_err1; | ||
| 670 | } | ||
| 671 | |||
| 672 | /* Map the memory of PMU reg base */ | ||
| 673 | pmu = pci_iomap(pdev, 0, 0); | ||
| 674 | if (!pmu) { | ||
| 675 | dev_err(&pdev->dev, "Unable to map the PMU address space\n"); | ||
| 676 | ret = -ENOMEM; | ||
| 677 | goto out_err2; | ||
| 678 | } | ||
| 679 | |||
| 680 | #ifdef CONFIG_DEBUG_FS | ||
| 681 | /* /sys/kernel/debug/mrst_pmu */ | ||
| 682 | (void) debugfs_create_file("mrst_pmu", S_IFREG | S_IRUGO, | ||
| 683 | NULL, NULL, &devices_state_operations); | ||
| 684 | #endif | ||
| 685 | pmu_reg = pmu; /* success */ | ||
| 686 | |||
| 687 | if (request_irq(pdev->irq, pmu_irq, 0, MRST_PMU_DRV_NAME, NULL)) { | ||
| 688 | dev_err(&pdev->dev, "Registering isr has failed\n"); | ||
| 689 | ret = -1; | ||
| 690 | goto out_err3; | ||
| 691 | } | ||
| 692 | |||
| 693 | pmu_scu_firmware_debug(); | ||
| 694 | |||
| 695 | pmu_write_wkc(S0I3_WAKE_SOURCES); /* Enable S0i3 wakeup sources */ | ||
| 696 | |||
| 697 | pmu_wait_ready(); | ||
| 698 | |||
| 699 | pmu_write_ssc(D0I1_ACG_SSS_TARGET); /* Enable Auto-Clock_Gating */ | ||
| 700 | pmu_write_cmd(0x201); | ||
| 701 | |||
| 702 | spin_lock_init(&mrst_pmu_power_state_lock); | ||
| 703 | |||
| 704 | /* Enable the hardware interrupt */ | ||
| 705 | pmu_irq_enable(); | ||
| 706 | return 0; | ||
| 707 | |||
| 708 | out_err3: | ||
| 709 | free_irq(pdev->irq, NULL); | ||
| 710 | pci_iounmap(pdev, pmu_reg); | ||
| 711 | pmu_reg = NULL; | ||
| 712 | out_err2: | ||
| 713 | pci_release_region(pdev, 0); | ||
| 714 | out_err1: | ||
| 715 | pci_disable_device(pdev); | ||
| 716 | return ret; | ||
| 717 | } | ||
| 718 | |||
| 719 | static void __devexit pmu_remove(struct pci_dev *pdev) | ||
| 720 | { | ||
| 721 | dev_err(&pdev->dev, "Mid PM pmu_remove called\n"); | ||
| 722 | |||
| 723 | /* Freeing up the irq */ | ||
| 724 | free_irq(pdev->irq, NULL); | ||
| 725 | |||
| 726 | pci_iounmap(pdev, pmu_reg); | ||
| 727 | pmu_reg = NULL; | ||
| 728 | |||
| 729 | /* disable the current PCI device */ | ||
| 730 | pci_release_region(pdev, 0); | ||
| 731 | pci_disable_device(pdev); | ||
| 732 | } | ||
| 733 | |||
| 734 | static DEFINE_PCI_DEVICE_TABLE(pmu_pci_ids) = { | ||
| 735 | { PCI_VDEVICE(INTEL, PCI_DEV_ID_MRST_PMU), 0 }, | ||
| 736 | { } | ||
| 737 | }; | ||
| 738 | |||
| 739 | MODULE_DEVICE_TABLE(pci, pmu_pci_ids); | ||
| 740 | |||
| 741 | static struct pci_driver driver = { | ||
| 742 | .name = MRST_PMU_DRV_NAME, | ||
| 743 | .id_table = pmu_pci_ids, | ||
| 744 | .probe = pmu_probe, | ||
| 745 | .remove = __devexit_p(pmu_remove), | ||
| 746 | }; | ||
| 747 | |||
| 748 | /** | ||
| 749 | * pmu_pci_register - register the PMU driver as PCI device | ||
| 750 | */ | ||
| 751 | static int __init pmu_pci_register(void) | ||
| 752 | { | ||
| 753 | return pci_register_driver(&driver); | ||
| 754 | } | ||
| 755 | |||
| 756 | /* Register and probe via fs_initcall() to preceed device_initcall() */ | ||
| 757 | fs_initcall(pmu_pci_register); | ||
| 758 | |||
| 759 | static void __exit mid_pci_cleanup(void) | ||
| 760 | { | ||
| 761 | pci_unregister_driver(&driver); | ||
| 762 | } | ||
| 763 | |||
| 764 | static int ia_major; | ||
| 765 | static int ia_minor; | ||
| 766 | |||
| 767 | static int pmu_sfi_parse_oem(struct sfi_table_header *table) | ||
| 768 | { | ||
| 769 | struct sfi_table_simple *sb; | ||
| 770 | |||
| 771 | sb = (struct sfi_table_simple *)table; | ||
| 772 | ia_major = (sb->pentry[1] >> 0) & 0xFFFF; | ||
| 773 | ia_minor = (sb->pentry[1] >> 16) & 0xFFFF; | ||
| 774 | printk(KERN_INFO "mrst_pmu: IA FW version v%x.%x\n", | ||
| 775 | ia_major, ia_minor); | ||
| 776 | |||
| 777 | return 0; | ||
| 778 | } | ||
| 779 | |||
| 780 | static int __init scu_fw_check(void) | ||
| 781 | { | ||
| 782 | int ret; | ||
| 783 | u32 fw_version; | ||
| 784 | |||
| 785 | if (!pmu_reg) | ||
| 786 | return 0; /* this driver didn't probe-out */ | ||
| 787 | |||
| 788 | sfi_table_parse("OEMB", NULL, NULL, pmu_sfi_parse_oem); | ||
| 789 | |||
| 790 | if (ia_major < 0x6005 || ia_minor < 0x1525) { | ||
| 791 | WARN(1, "mrst_pmu: IA FW version too old\n"); | ||
| 792 | return -1; | ||
| 793 | } | ||
| 794 | |||
| 795 | ret = intel_scu_ipc_command(IPCMSG_FW_REVISION, 0, NULL, 0, | ||
| 796 | &fw_version, 1); | ||
| 797 | |||
| 798 | if (ret) { | ||
| 799 | WARN(1, "mrst_pmu: IPC FW version? %d\n", ret); | ||
| 800 | } else { | ||
| 801 | int scu_major = (fw_version >> 8) & 0xFF; | ||
| 802 | int scu_minor = (fw_version >> 0) & 0xFF; | ||
| 803 | |||
| 804 | printk(KERN_INFO "mrst_pmu: firmware v%x\n", fw_version); | ||
| 805 | |||
| 806 | if ((scu_major >= 0xC0) && (scu_minor >= 0x49)) { | ||
| 807 | printk(KERN_INFO "mrst_pmu: enabling S0i3\n"); | ||
| 808 | mrst_pmu_s0i3_enable = true; | ||
| 809 | } else { | ||
| 810 | WARN(1, "mrst_pmu: S0i3 disabled, old firmware %X.%X", | ||
| 811 | scu_major, scu_minor); | ||
| 812 | } | ||
| 813 | } | ||
| 814 | return 0; | ||
| 815 | } | ||
| 816 | late_initcall(scu_fw_check); | ||
| 817 | module_exit(mid_pci_cleanup); | ||
diff --git a/arch/x86/platform/mrst/pmu.h b/arch/x86/platform/mrst/pmu.h new file mode 100644 index 00000000000..bfbfe64b167 --- /dev/null +++ b/arch/x86/platform/mrst/pmu.h | |||
| @@ -0,0 +1,234 @@ | |||
| 1 | /* | ||
| 2 | * mrst/pmu.h - private definitions for MRST Power Management Unit mrst/pmu.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011, Intel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License along with | ||
| 16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef _MRST_PMU_H_ | ||
| 21 | #define _MRST_PMU_H_ | ||
| 22 | |||
| 23 | #define PCI_DEV_ID_MRST_PMU 0x0810 | ||
| 24 | #define MRST_PMU_DRV_NAME "mrst_pmu" | ||
| 25 | #define PCI_SUB_CLASS_MASK 0xFF00 | ||
| 26 | |||
| 27 | #define PCI_VENDOR_CAP_LOG_ID_MASK 0x7F | ||
| 28 | #define PCI_VENDOR_CAP_LOG_SS_MASK 0x80 | ||
| 29 | |||
| 30 | #define SUB_SYS_ALL_D0I1 0x01155555 | ||
| 31 | #define S0I3_WAKE_SOURCES 0x00001FFF | ||
| 32 | |||
| 33 | #define PM_S0I3_COMMAND \ | ||
| 34 | ((0 << 31) | /* Reserved */ \ | ||
| 35 | (0 << 30) | /* Core must be idle */ \ | ||
| 36 | (0xc2 << 22) | /* ACK C6 trigger */ \ | ||
| 37 | (3 << 19) | /* Trigger on DMI message */ \ | ||
| 38 | (3 << 16) | /* Enter S0i3 */ \ | ||
| 39 | (0 << 13) | /* Numeric mode ID (sw) */ \ | ||
| 40 | (3 << 9) | /* Trigger mode */ \ | ||
| 41 | (0 << 8) | /* Do not interrupt */ \ | ||
| 42 | (1 << 0)) /* Set configuration */ | ||
| 43 | |||
| 44 | #define LSS_DMI 0 | ||
| 45 | #define LSS_SD_HC0 1 | ||
| 46 | #define LSS_SD_HC1 2 | ||
| 47 | #define LSS_NAND 3 | ||
| 48 | #define LSS_IMAGING 4 | ||
| 49 | #define LSS_SECURITY 5 | ||
| 50 | #define LSS_DISPLAY 6 | ||
| 51 | #define LSS_USB_HC 7 | ||
| 52 | #define LSS_USB_OTG 8 | ||
| 53 | #define LSS_AUDIO 9 | ||
| 54 | #define LSS_AUDIO_LPE 9 | ||
| 55 | #define LSS_AUDIO_SSP 9 | ||
| 56 | #define LSS_I2C0 10 | ||
| 57 | #define LSS_I2C1 10 | ||
| 58 | #define LSS_I2C2 10 | ||
| 59 | #define LSS_KBD 10 | ||
| 60 | #define LSS_SPI0 10 | ||
| 61 | #define LSS_SPI1 10 | ||
| 62 | #define LSS_SPI2 10 | ||
| 63 | #define LSS_GPIO 10 | ||
| 64 | #define LSS_SRAM 11 /* used by SCU, do not touch */ | ||
| 65 | #define LSS_SD_HC2 12 | ||
| 66 | /* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */ | ||
| 67 | #define MRST_NUM_LSS 13 | ||
| 68 | |||
| 69 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) | ||
| 70 | |||
| 71 | #define SSMSK(mask, lss) ((mask) << ((lss) * 2)) | ||
| 72 | #define D0 0 | ||
| 73 | #define D0i1 1 | ||
| 74 | #define D0i2 2 | ||
| 75 | #define D0i3 3 | ||
| 76 | |||
| 77 | #define S0I3_SSS_TARGET ( \ | ||
| 78 | SSMSK(D0i1, LSS_DMI) | \ | ||
| 79 | SSMSK(D0i3, LSS_SD_HC0) | \ | ||
| 80 | SSMSK(D0i3, LSS_SD_HC1) | \ | ||
| 81 | SSMSK(D0i3, LSS_NAND) | \ | ||
| 82 | SSMSK(D0i3, LSS_SD_HC2) | \ | ||
| 83 | SSMSK(D0i3, LSS_IMAGING) | \ | ||
| 84 | SSMSK(D0i3, LSS_SECURITY) | \ | ||
| 85 | SSMSK(D0i3, LSS_DISPLAY) | \ | ||
| 86 | SSMSK(D0i3, LSS_USB_HC) | \ | ||
| 87 | SSMSK(D0i3, LSS_USB_OTG) | \ | ||
| 88 | SSMSK(D0i3, LSS_AUDIO) | \ | ||
| 89 | SSMSK(D0i1, LSS_I2C0)) | ||
| 90 | |||
| 91 | /* | ||
| 92 | * D0i1 on Langwell is Autonomous Clock Gating (ACG). | ||
| 93 | * Enable ACG on every LSS except camera and audio | ||
| 94 | */ | ||
| 95 | #define D0I1_ACG_SSS_TARGET \ | ||
| 96 | (SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO)) | ||
| 97 | |||
| 98 | enum cm_mode { | ||
| 99 | CM_NOP, /* ignore the config mode value */ | ||
| 100 | CM_IMMEDIATE, | ||
| 101 | CM_DELAY, | ||
| 102 | CM_TRIGGER, | ||
| 103 | CM_INVALID | ||
| 104 | }; | ||
| 105 | |||
| 106 | enum sys_state { | ||
| 107 | SYS_STATE_S0I0, | ||
| 108 | SYS_STATE_S0I1, | ||
| 109 | SYS_STATE_S0I2, | ||
| 110 | SYS_STATE_S0I3, | ||
| 111 | SYS_STATE_S3, | ||
| 112 | SYS_STATE_S5 | ||
| 113 | }; | ||
| 114 | |||
| 115 | #define SET_CFG_CMD 1 | ||
| 116 | |||
| 117 | enum int_status { | ||
| 118 | INT_SPURIOUS = 0, | ||
| 119 | INT_CMD_DONE = 1, | ||
| 120 | INT_CMD_ERR = 2, | ||
| 121 | INT_WAKE_RX = 3, | ||
| 122 | INT_SS_ERROR = 4, | ||
| 123 | INT_S0IX_MISS = 5, | ||
| 124 | INT_NO_ACKC6 = 6, | ||
| 125 | INT_INVALID = 7, | ||
| 126 | }; | ||
| 127 | |||
| 128 | /* PMU register interface */ | ||
| 129 | static struct mrst_pmu_reg { | ||
| 130 | u32 pm_sts; /* 0x00 */ | ||
| 131 | u32 pm_cmd; /* 0x04 */ | ||
| 132 | u32 pm_ics; /* 0x08 */ | ||
| 133 | u32 _resv1; /* 0x0C */ | ||
| 134 | u32 pm_wkc[2]; /* 0x10 */ | ||
| 135 | u32 pm_wks[2]; /* 0x18 */ | ||
| 136 | u32 pm_ssc[4]; /* 0x20 */ | ||
| 137 | u32 pm_sss[4]; /* 0x30 */ | ||
| 138 | u32 pm_wssc[4]; /* 0x40 */ | ||
| 139 | u32 pm_c3c4; /* 0x50 */ | ||
| 140 | u32 pm_c5c6; /* 0x54 */ | ||
| 141 | u32 pm_msi_disable; /* 0x58 */ | ||
| 142 | } *pmu_reg; | ||
| 143 | |||
| 144 | static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); } | ||
| 145 | static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); } | ||
| 146 | static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); } | ||
| 147 | static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); } | ||
| 148 | |||
| 149 | static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); } | ||
| 150 | static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); } | ||
| 151 | static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); } | ||
| 152 | static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); } | ||
| 153 | static inline void pmu_write_wssc(u32 arg) | ||
| 154 | { writel(arg, &pmu_reg->pm_wssc[0]); } | ||
| 155 | |||
| 156 | static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); } | ||
| 157 | static inline u32 pmu_msi_is_disabled(void) | ||
| 158 | { return readl(&pmu_reg->pm_msi_disable); } | ||
| 159 | |||
| 160 | union pmu_pm_ics { | ||
| 161 | struct { | ||
| 162 | u32 cause:8; | ||
| 163 | u32 enable:1; | ||
| 164 | u32 pending:1; | ||
| 165 | u32 reserved:22; | ||
| 166 | } bits; | ||
| 167 | u32 value; | ||
| 168 | }; | ||
| 169 | |||
| 170 | static inline void pmu_irq_enable(void) | ||
| 171 | { | ||
| 172 | union pmu_pm_ics pmu_ics; | ||
| 173 | |||
| 174 | pmu_ics.value = pmu_read_ics(); | ||
| 175 | pmu_ics.bits.enable = 1; | ||
| 176 | pmu_write_ics(pmu_ics.value); | ||
| 177 | } | ||
| 178 | |||
| 179 | union pmu_pm_status { | ||
| 180 | struct { | ||
| 181 | u32 pmu_rev:8; | ||
| 182 | u32 pmu_busy:1; | ||
| 183 | u32 mode_id:4; | ||
| 184 | u32 Reserved:19; | ||
| 185 | } pmu_status_parts; | ||
| 186 | u32 pmu_status_value; | ||
| 187 | }; | ||
| 188 | |||
| 189 | static inline int pmu_read_busy_status(void) | ||
| 190 | { | ||
| 191 | union pmu_pm_status result; | ||
| 192 | |||
| 193 | result.pmu_status_value = pmu_read_sts(); | ||
| 194 | |||
| 195 | return result.pmu_status_parts.pmu_busy; | ||
| 196 | } | ||
| 197 | |||
| 198 | /* pmu set config parameters */ | ||
| 199 | struct cfg_delay_param_t { | ||
| 200 | u32 cmd:8; | ||
| 201 | u32 ioc:1; | ||
| 202 | u32 cfg_mode:4; | ||
| 203 | u32 mode_id:3; | ||
| 204 | u32 sys_state:3; | ||
| 205 | u32 cfg_delay:8; | ||
| 206 | u32 rsvd:5; | ||
| 207 | }; | ||
| 208 | |||
| 209 | struct cfg_trig_param_t { | ||
| 210 | u32 cmd:8; | ||
| 211 | u32 ioc:1; | ||
| 212 | u32 cfg_mode:4; | ||
| 213 | u32 mode_id:3; | ||
| 214 | u32 sys_state:3; | ||
| 215 | u32 cfg_trig_type:3; | ||
| 216 | u32 cfg_trig_val:8; | ||
| 217 | u32 cmbi:1; | ||
| 218 | u32 rsvd1:1; | ||
| 219 | }; | ||
| 220 | |||
| 221 | union pmu_pm_set_cfg_cmd_t { | ||
| 222 | union { | ||
| 223 | struct cfg_delay_param_t d_param; | ||
| 224 | struct cfg_trig_param_t t_param; | ||
| 225 | } pmu2_params; | ||
| 226 | u32 pmu_pm_set_cfg_cmd_value; | ||
| 227 | }; | ||
| 228 | |||
| 229 | #ifdef FUTURE_PATCH | ||
| 230 | extern int mrst_s0i3_entry(u32 regval, u32 *regaddr); | ||
| 231 | #else | ||
| 232 | static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; } | ||
| 233 | #endif | ||
| 234 | #endif | ||
