Before testing for VFP, make sure CP10 is enabled. (And CP11 for Neon too).diff -r1.66 -r1.67 src/sys/arch/arm/include/armreg.h
(matt)
--- src/sys/arch/arm/include/armreg.h 2012/09/22 00:33:37 1.66
+++ src/sys/arch/arm/include/armreg.h 2012/09/22 01:44:12 1.67
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: armreg.h,v 1.66 2012/09/22 00:33:37 matt Exp $ */ | 1 | /* $NetBSD: armreg.h,v 1.67 2012/09/22 01:44:12 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1998, 2001 Ben Harris | 4 | * Copyright (c) 1998, 2001 Ben Harris | |
5 | * Copyright (c) 1994-1996 Mark Brinicombe. | 5 | * Copyright (c) 1994-1996 Mark Brinicombe. | |
6 | * Copyright (c) 1994 Brini. | 6 | * Copyright (c) 1994 Brini. | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * This code is derived from software written for Brini by Mark Brinicombe | 9 | * This code is derived from software written for Brini by Mark Brinicombe | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -559,26 +559,29 @@ ARMREG_READ_INLINE(mmfr0, "p15,0,%0,c0,c | @@ -559,26 +559,29 @@ ARMREG_READ_INLINE(mmfr0, "p15,0,%0,c0,c | |||
559 | ARMREG_READ_INLINE(mmfr1, "p15,0,%0,c0,c1,5") /* Memory Model Feature Register 1 */ | 559 | ARMREG_READ_INLINE(mmfr1, "p15,0,%0,c0,c1,5") /* Memory Model Feature Register 1 */ | |
560 | ARMREG_READ_INLINE(mmfr2, "p15,0,%0,c0,c1,6") /* Memory Model Feature Register 2 */ | 560 | ARMREG_READ_INLINE(mmfr2, "p15,0,%0,c0,c1,6") /* Memory Model Feature Register 2 */ | |
561 | ARMREG_READ_INLINE(mmfr3, "p15,0,%0,c0,c1,7") /* Memory Model Feature Register 3 */ | 561 | ARMREG_READ_INLINE(mmfr3, "p15,0,%0,c0,c1,7") /* Memory Model Feature Register 3 */ | |
562 | ARMREG_READ_INLINE(isar0, "p15,0,%0,c0,c2,0") /* Instruction Set Attribute Register 0 */ | 562 | ARMREG_READ_INLINE(isar0, "p15,0,%0,c0,c2,0") /* Instruction Set Attribute Register 0 */ | |
563 | ARMREG_READ_INLINE(isar1, "p15,0,%0,c0,c2,1") /* Instruction Set Attribute Register 1 */ | 563 | ARMREG_READ_INLINE(isar1, "p15,0,%0,c0,c2,1") /* Instruction Set Attribute Register 1 */ | |
564 | ARMREG_READ_INLINE(isar2, "p15,0,%0,c0,c2,2") /* Instruction Set Attribute Register 2 */ | 564 | ARMREG_READ_INLINE(isar2, "p15,0,%0,c0,c2,2") /* Instruction Set Attribute Register 2 */ | |
565 | ARMREG_READ_INLINE(isar3, "p15,0,%0,c0,c2,3") /* Instruction Set Attribute Register 3 */ | 565 | ARMREG_READ_INLINE(isar3, "p15,0,%0,c0,c2,3") /* Instruction Set Attribute Register 3 */ | |
566 | ARMREG_READ_INLINE(isar4, "p15,0,%0,c0,c2,4") /* Instruction Set Attribute Register 4 */ | 566 | ARMREG_READ_INLINE(isar4, "p15,0,%0,c0,c2,4") /* Instruction Set Attribute Register 4 */ | |
567 | ARMREG_READ_INLINE(isar5, "p15,0,%0,c0,c2,5") /* Instruction Set Attribute Register 5 */ | 567 | ARMREG_READ_INLINE(isar5, "p15,0,%0,c0,c2,5") /* Instruction Set Attribute Register 5 */ | |
568 | ARMREG_READ_INLINE(ccsidr, "p15,1,%0,c0,c0,0") /* Cache Size ID Register */ | 568 | ARMREG_READ_INLINE(ccsidr, "p15,1,%0,c0,c0,0") /* Cache Size ID Register */ | |
569 | ARMREG_READ_INLINE(clidr, "p15,1,%0,c0,c0,1") /* Cache Level ID Register */ | 569 | ARMREG_READ_INLINE(clidr, "p15,1,%0,c0,c0,1") /* Cache Level ID Register */ | |
570 | ARMREG_READ_INLINE(csselr, "p15,2,%0,c0,c0,0") /* Cache Size Selection Register */ | 570 | ARMREG_READ_INLINE(csselr, "p15,2,%0,c0,c0,0") /* Cache Size Selection Register */ | |
571 | ARMREG_WRITE_INLINE(csselr, "p15,2,%0,c0,c0,0") /* Cache Size Selection Register */ | 571 | ARMREG_WRITE_INLINE(csselr, "p15,2,%0,c0,c0,0") /* Cache Size Selection Register */ | |
572 | /* c1 registers */ | |||
573 | ARMREG_READ_INLINE(cpacr, "p15,0,%0,c1,c0,2") /* Co-Processor Access Register */ | |||
574 | ARMREG_WRITE_INLINE(cpacr, "p15,0,%0,c1,c0,2") /* Co-Processor Access Register */ | |||
572 | /* c2 registers */ | 575 | /* c2 registers */ | |
573 | ARMREG_READ_INLINE(ttbr, "p15,0,%0,c2,c0,0") /* Translation Table Base Register 0 */ | 576 | ARMREG_READ_INLINE(ttbr, "p15,0,%0,c2,c0,0") /* Translation Table Base Register 0 */ | |
574 | ARMREG_WRITE_INLINE(ttbr, "p15,0,%0,c2,c0,0") /* Translation Table Base Register 0 */ | 577 | ARMREG_WRITE_INLINE(ttbr, "p15,0,%0,c2,c0,0") /* Translation Table Base Register 0 */ | |
575 | ARMREG_READ_INLINE(ttbr1, "p15,0,%0,c2,c0,1") /* Translation Table Base Register 1 */ | 578 | ARMREG_READ_INLINE(ttbr1, "p15,0,%0,c2,c0,1") /* Translation Table Base Register 1 */ | |
576 | ARMREG_WRITE_INLINE(ttbr1, "p15,0,%0,c2,c0,1") /* Translation Table Base Register 1 */ | 579 | ARMREG_WRITE_INLINE(ttbr1, "p15,0,%0,c2,c0,1") /* Translation Table Base Register 1 */ | |
577 | ARMREG_READ_INLINE(ttbcr, "p15,0,%0,c2,c0,2") /* Translation Table Base Register */ | 580 | ARMREG_READ_INLINE(ttbcr, "p15,0,%0,c2,c0,2") /* Translation Table Base Register */ | |
578 | ARMREG_WRITE_INLINE(ttbcr, "p15,0,%0,c2,c0,2") /* Translation Table Base Register */ | 581 | ARMREG_WRITE_INLINE(ttbcr, "p15,0,%0,c2,c0,2") /* Translation Table Base Register */ | |
579 | /* c5 registers */ | 582 | /* c5 registers */ | |
580 | ARMREG_READ_INLINE(dfsr, "p15,0,%0,c5,c0,0") /* Data Fault Status Register */ | 583 | ARMREG_READ_INLINE(dfsr, "p15,0,%0,c5,c0,0") /* Data Fault Status Register */ | |
581 | ARMREG_READ_INLINE(ifsr, "p15,0,%0,c5,c0,1") /* Instruction Fault Status Register */ | 584 | ARMREG_READ_INLINE(ifsr, "p15,0,%0,c5,c0,1") /* Instruction Fault Status Register */ | |
582 | /* c6 registers */ | 585 | /* c6 registers */ | |
583 | ARMREG_READ_INLINE(dfar, "p15,0,%0,c6,c0,0") /* Data Fault Address Register */ | 586 | ARMREG_READ_INLINE(dfar, "p15,0,%0,c6,c0,0") /* Data Fault Address Register */ | |
584 | ARMREG_READ_INLINE(ifar, "p15,0,%0,c6,c0,2") /* Instruction Fault Address Register */ | 587 | ARMREG_READ_INLINE(ifar, "p15,0,%0,c6,c0,2") /* Instruction Fault Address Register */ |
--- src/sys/arch/arm/include/vfpreg.h 2012/08/16 07:24:25 1.4
+++ src/sys/arch/arm/include/vfpreg.h 2012/09/22 01:44:12 1.5
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vfpreg.h,v 1.4 2012/08/16 07:24:25 matt Exp $ */ | 1 | /* $NetBSD: vfpreg.h,v 1.5 2012/09/22 01:44:12 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2008 ARM Ltd | 4 | * Copyright (c) 2008 ARM Ltd | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -38,33 +38,35 @@ | @@ -38,33 +38,35 @@ | |||
38 | #define VFP_FPSID_IMP_ARM 0x41000000 /* Implementer: ARM */ | 38 | #define VFP_FPSID_IMP_ARM 0x41000000 /* Implementer: ARM */ | |
39 | #define VFP_FPSID_SW 0x00800000 /* VFP implemented in SW */ | 39 | #define VFP_FPSID_SW 0x00800000 /* VFP implemented in SW */ | |
40 | #define VFP_FPSID_FMT_MSK 0x00600000 /* FLDMX/FSTMX Format */ | 40 | #define VFP_FPSID_FMT_MSK 0x00600000 /* FLDMX/FSTMX Format */ | |
41 | #define VFP_FPSID_FMT_1 0x00000000 /* Standard format 1 */ | 41 | #define VFP_FPSID_FMT_1 0x00000000 /* Standard format 1 */ | |
42 | #define VFP_FPSID_FMT_2 0x00200000 /* Standard format 2 */ | 42 | #define VFP_FPSID_FMT_2 0x00200000 /* Standard format 2 */ | |
43 | #define VFP_FPSID_FMT_WEIRD 0x00600000 /* Non-standard format */ | 43 | #define VFP_FPSID_FMT_WEIRD 0x00600000 /* Non-standard format */ | |
44 | #define VFP_FPSID_SP 0x00100000 /* Only single precision */ | 44 | #define VFP_FPSID_SP 0x00100000 /* Only single precision */ | |
45 | #define VFP_FPSID_ARCH_MSK 0x000f0000 /* Architecture */ | 45 | #define VFP_FPSID_ARCH_MSK 0x000f0000 /* Architecture */ | |
46 | #define VFP_FPSID_ARCH_V1 0x00000000 /* Arch VFPv1 */ | 46 | #define VFP_FPSID_ARCH_V1 0x00000000 /* Arch VFPv1 */ | |
47 | #define VFP_FPSID_ARCH_V2 0x00010000 /* Arch VFPv2 */ | 47 | #define VFP_FPSID_ARCH_V2 0x00010000 /* Arch VFPv2 */ | |
48 | #define VFP_FPSID_PART_MSK 0x0000ff00 /* Part number */ | 48 | #define VFP_FPSID_PART_MSK 0x0000ff00 /* Part number */ | |
49 | #define VFP_FPSID_PART_VFP10 0x00001000 /* VFP10 */ | 49 | #define VFP_FPSID_PART_VFP10 0x00001000 /* VFP10 */ | |
50 | #define VFP_FPSID_PART_VFP11 0x00002000 /* VFP11 */ | 50 | #define VFP_FPSID_PART_VFP11 0x00002000 /* VFP11 */ | |
51 | #define VFP_FPSID_PART_VFP30 0x00003000 /* VFP30 */ | |||
51 | #define VFP_FPSID_VAR_MSK 0x000000f0 /* Variant */ | 52 | #define VFP_FPSID_VAR_MSK 0x000000f0 /* Variant */ | |
52 | #define VFP_FPSID_VAR_ARM10 0x000000a0 /* Variant ARM10 */ | 53 | #define VFP_FPSID_VAR_ARM10 0x000000a0 /* Variant ARM10 */ | |
53 | #define VFP_FPSID_VAR_ARM11 0x000000b0 /* Variant ARM11 */ | 54 | #define VFP_FPSID_VAR_ARM11 0x000000b0 /* Variant ARM11 */ | |
54 | #define VFP_FPSID_REV_MSK 0x0000000f /* Revision */ | 55 | #define VFP_FPSID_REV_MSK 0x0000000f /* Revision */ | |
55 | 56 | |||
56 | #define FPU_VFP10_ARM10E 0x410001a0 /* Really a VFPv2 part */ | 57 | #define FPU_VFP10_ARM10E 0x410001a0 /* Really a VFPv2 part */ | |
57 | #define FPU_VFP11_ARM11 0x410120b0 | 58 | #define FPU_VFP11_ARM11 0x410120b0 | |
59 | #define FPU_VFP30_CORTEXA9 0x41033090 | |||
58 | 60 | |||
59 | #define VFP_FPEXC_EX 0x80000000 /* Exception status bit */ | 61 | #define VFP_FPEXC_EX 0x80000000 /* Exception status bit */ | |
60 | #define VFP_FPEXC_EN 0x40000000 /* VFP Enable bit */ | 62 | #define VFP_FPEXC_EN 0x40000000 /* VFP Enable bit */ | |
61 | #define VFP_FPEXC_FP2V 0x10000000 /* FPINST2 instruction valid */ | 63 | #define VFP_FPEXC_FP2V 0x10000000 /* FPINST2 instruction valid */ | |
62 | #define VFP_FPEXC_VECITR 0x00000700 /* Vector iteration count */ | 64 | #define VFP_FPEXC_VECITR 0x00000700 /* Vector iteration count */ | |
63 | #define VFP_FPEXC_INV 0x00000080 /* Input exception flag */ | 65 | #define VFP_FPEXC_INV 0x00000080 /* Input exception flag */ | |
64 | #define VFP_FPEXC_UFC 0x00000080 /* Potential underflow flag */ | 66 | #define VFP_FPEXC_UFC 0x00000080 /* Potential underflow flag */ | |
65 | #define VFP_FPEXC_OFC 0x00000080 /* Potential overflow flag */ | 67 | #define VFP_FPEXC_OFC 0x00000080 /* Potential overflow flag */ | |
66 | #define VFP_FPEXC_IOC 0x00000080 /* Potential inv. op. flag */ | 68 | #define VFP_FPEXC_IOC 0x00000080 /* Potential inv. op. flag */ | |
67 | 69 | |||
68 | #define VFP_FPSCR_N 0x80000000 /* set if compare <= result */ | 70 | #define VFP_FPSCR_N 0x80000000 /* set if compare <= result */ | |
69 | #define VFP_FPSCR_Z 0x40000000 /* set if compare = result */ | 71 | #define VFP_FPSCR_Z 0x40000000 /* set if compare = result */ | |
70 | #define VFP_FPSCR_C 0x20000000 /* set if compare (=,>=,UNORD) result */ | 72 | #define VFP_FPSCR_C 0x20000000 /* set if compare (=,>=,UNORD) result */ |
--- src/sys/arch/arm/vfp/vfp_init.c 2012/08/16 18:16:25 1.5
+++ src/sys/arch/arm/vfp/vfp_init.c 2012/09/22 01:44:12 1.6
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vfp_init.c,v 1.5 2012/08/16 18:16:25 matt Exp $ */ | 1 | /* $NetBSD: vfp_init.c,v 1.6 2012/09/22 01:44:12 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2008 ARM Ltd | 4 | * Copyright (c) 2008 ARM Ltd | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -212,55 +212,75 @@ vfp_attach(void) | @@ -212,55 +212,75 @@ vfp_attach(void) | |||
212 | 212 | |||
213 | #else | 213 | #else | |
214 | void | 214 | void | |
215 | vfp_attach(void) | 215 | vfp_attach(void) | |
216 | { | 216 | { | |
217 | struct cpu_info * const ci = curcpu(); | 217 | struct cpu_info * const ci = curcpu(); | |
218 | const char *model = NULL; | 218 | const char *model = NULL; | |
219 | void *uh; | 219 | void *uh; | |
220 | 220 | |||
221 | uh = install_coproc_handler(VFP_COPROC, vfp_test); | 221 | uh = install_coproc_handler(VFP_COPROC, vfp_test); | |
222 | 222 | |||
223 | undefined_test = 0; | 223 | undefined_test = 0; | |
224 | 224 | |||
225 | #ifdef FPU_VFP | |||
226 | uint32_t cpacr = armreg_cpacr_read(); | |||
227 | cpacr &= ~__BITS(21,20); | |||
228 | cpacr &= ~__BITS(23,22); | |||
229 | ||||
230 | cpacr |= __SHIFTIN(1, __BITS(21,20)); | |||
231 | cpacr |= __SHIFTIN(1, __BITS(23,22)); | |||
232 | armreg_cpacr_write(cpacr); | |||
233 | cpacr = armreg_cpacr_read(); | |||
234 | if ((cpacr & __BITS(23,22)) == 0) { | |||
235 | aprint_normal_dev(ci->ci_dev, "NEON not present\n"); | |||
236 | } | |||
237 | if ((cpacr & __BITS(21,20)) == 0) { | |||
238 | aprint_normal_dev(ci->ci_dev, "VFP not present\n"); | |||
239 | } | |||
240 | #endif | |||
241 | ||||
225 | const uint32_t fpsid = read_fpsid(); | 242 | const uint32_t fpsid = read_fpsid(); | |
226 | 243 | |||
227 | remove_coproc_handler(uh); | 244 | remove_coproc_handler(uh); | |
228 | 245 | |||
229 | if (undefined_test != 0) { | 246 | if (undefined_test != 0) { | |
230 | aprint_normal_dev(ci->ci_dev, "No VFP detected\n"); | 247 | aprint_normal_dev(ci->ci_dev, "No VFP detected\n"); | |
231 | install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); | 248 | install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); | |
232 | ci->ci_vfp_id = 0; | 249 | ci->ci_vfp_id = 0; | |
233 | return; | 250 | return; | |
234 | } | 251 | } | |
235 | 252 | |||
236 | ci->ci_vfp_id = fpsid; | 253 | ci->ci_vfp_id = fpsid; | |
237 | switch (fpsid & ~ VFP_FPSID_REV_MSK) { | 254 | switch (fpsid & ~ VFP_FPSID_REV_MSK) { | |
238 | case FPU_VFP10_ARM10E: | 255 | case FPU_VFP10_ARM10E: | |
239 | model = "VFP10 R1"; | 256 | model = "VFP10 R1"; | |
240 | break; | 257 | break; | |
241 | case FPU_VFP11_ARM11: | 258 | case FPU_VFP11_ARM11: | |
242 | model = "VFP11"; | 259 | model = "VFP11"; | |
243 | break; | 260 | break; | |
261 | case FPU_VFP30_CORTEXA9: | |||
262 | model = "NEON MPE w/ VFP 3.0"; | |||
263 | break; | |||
244 | default: | 264 | default: | |
245 | aprint_normal_dev(ci->ci_dev, "unrecognized VFP version %x\n", | 265 | aprint_normal_dev(ci->ci_dev, "unrecognized VFP version %x\n", | |
246 | fpsid); | 266 | fpsid); | |
247 | install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); | 267 | install_coproc_handler(VFP_COPROC, vfp_fpscr_handler); | |
248 | return; | 268 | return; | |
249 | } | 269 | } | |
250 | 270 | |||
251 | if (fpsid != 0) { | 271 | if (fpsid != 0) { | |
252 | aprint_normal("vfp%d at %s: %s\n", | 272 | aprint_normal("vfp%d at %s: %s\n", | |
253 | curcpu()->ci_dev->dv_unit, curcpu()->ci_dev->dv_xname, | 273 | device_unit(curcpu()->ci_dev), device_xname(curcpu()->ci_dev), | |
254 | model); | 274 | model); | |
255 | } | 275 | } | |
256 | evcnt_attach_dynamic(&vfpevent_use, EVCNT_TYPE_MISC, NULL, | 276 | evcnt_attach_dynamic(&vfpevent_use, EVCNT_TYPE_MISC, NULL, | |
257 | "VFP", "proc use"); | 277 | "VFP", "proc use"); | |
258 | evcnt_attach_dynamic(&vfpevent_reuse, EVCNT_TYPE_MISC, NULL, | 278 | evcnt_attach_dynamic(&vfpevent_reuse, EVCNT_TYPE_MISC, NULL, | |
259 | "VFP", "proc re-use"); | 279 | "VFP", "proc re-use"); | |
260 | install_coproc_handler(VFP_COPROC, vfp_handler); | 280 | install_coproc_handler(VFP_COPROC, vfp_handler); | |
261 | install_coproc_handler(VFP_COPROC2, vfp_handler); | 281 | install_coproc_handler(VFP_COPROC2, vfp_handler); | |
262 | } | 282 | } | |
263 | 283 | |||
264 | /* The real handler for VFP bounces. */ | 284 | /* The real handler for VFP bounces. */ | |
265 | static int | 285 | static int | |
266 | vfp_handler(u_int address, u_int insn, trapframe_t *frame, | 286 | vfp_handler(u_int address, u_int insn, trapframe_t *frame, |