Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/sparc/Makefile.sparc
+++ new/usr/src/uts/sparc/Makefile.sparc
1 1 #
2 2 # CDDL HEADER START
3 3 #
4 4 # The contents of this file are subject to the terms of the
5 5 # Common Development and Distribution License (the "License").
6 6 # You may not use this file except in compliance with the License.
7 7 #
8 8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 # or http://www.opensolaris.org/os/licensing.
10 10 # See the License for the specific language governing permissions
11 11 # and limitations under the License.
12 12 #
13 13 # When distributing Covered Code, include this CDDL HEADER in each
14 14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 # If applicable, add the following below this CDDL HEADER, with the
16 16 # fields enclosed by brackets "[]" replaced with your own identifying
17 17 # information: Portions Copyright [yyyy] [name of copyright owner]
18 18 #
19 19 # CDDL HEADER END
20 20 #
21 21
22 22 # Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 # Copyright (c) 2013 Andrew Stormont. All rights reserved.
24 24 # Copyright (c) 2015, Joyent, Inc. All rights reserved.
25 25 # Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 26 # Copyright 2016 Gary Mills
27 27
28 28
29 29 #
30 30 # This makefile contains the common definitions for all sparc
31 31 # implementation architecture independent modules.
32 32 #
33 33
34 34 #
35 35 # Define supported builds
36 36 #
37 37 DEF_BUILDS = $(DEF_BUILDS64)
38 38 ALL_BUILDS = $(ALL_BUILDS64)
39 39
40 40 #
41 41 # Everybody needs to know how to build modstubs.o and to locate unix.o.
42 42 # Note that unix.o must currently be selected from among the possible
43 43 # "implementation architectures". Note further, that unix.o is only
44 44 # used as an optional error check for undefines so (theoretically)
45 45 # any "implementation architectures" could be used. We choose sun4u
46 46 # because it is the reference port.
47 47 #
48 48 UNIX_DIR = $(UTSBASE)/sun4u/unix
49 49 GENLIB_DIR = $(UTSBASE)/sun4u/genunix
50 50 IPDRV_DIR = $(UTSBASE)/sparc/ip
51 51 MODSTUBS_DIR = $(UNIX_DIR)
52 52 DSF_DIR = $(UNIX_DIR)
53 53 LINTS_DIR = $(OBJS_DIR)
54 54 LINT_LIB_DIR = $(UTSBASE)/sparc/lint-libs/$(OBJS_DIR)
55 55
56 56 UNIX_O = $(UNIX_DIR)/$(OBJS_DIR)/unix.o
57 57 MODSTUBS_O = $(MODSTUBS_DIR)/$(OBJS_DIR)/modstubs.o
58 58 GENLIB = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/libgenunix.so
59 59
60 60 LINT_LIB_32 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lunix.ln
61 61 GEN_LINT_LIB_32 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lgenunix.ln
62 62
63 63 LINT_LIB_64 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lunix.ln
64 64 GEN_LINT_LIB_64 = $(UTSBASE)/sun4u/lint-libs/$(OBJS_DIR)/llib-lgenunix.ln
65 65
66 66 LINT_LIB = $(LINT_LIB_$(CLASS))
67 67 GEN_LINT_LIB = $(GEN_LINT_LIB_$(CLASS))
68 68
69 69 LINT32_DIRS = $(LINT32_BUILDS:%=$(UTSBASE)/sparc/lint-libs/%)
70 70 LINT32_FILES = $(LINT32_DIRS:%=%/llib-l$(MODULE).ln)
71 71
72 72 LINT64_DIRS = $(LINT64_BUILDS:%=$(UTSBASE)/sparc/lint-libs/%)
73 73 LINT64_FILES = $(LINT64_DIRS:%=%/llib-l$(MODULE).ln)
74 74
75 75 #
76 76 # Include the makefiles which define build rule templates, the
77 77 # collection of files per module, and a few specific flags. Note
78 78 # that order is significant, just as with an include path. The
79 79 # first build rule template which matches the files name will be
80 80 # used. By including these in order from most machine dependent
81 81 # to most machine independent, we allow a machine dependent file
82 82 # to be used in preference over a machine independent version
83 83 # (Such as a machine specific optimization, which preserves the
84 84 # interfaces.)
85 85 #
86 86 include $(UTSBASE)/sparc/Makefile.files
87 87 include $(UTSBASE)/sparc/v9/Makefile.files
88 88 include $(UTSBASE)/sun/Makefile.files
89 89 include $(UTSBASE)/common/Makefile.files
90 90
91 91 #
92 92 # ----- TRANSITIONAL SECTION --------------------------------------------------
93 93 #
94 94
95 95 #
96 96 # Not everything which *should* be a module is a module yet. The
97 97 # following is a list of such objects which are currently part of
98 98 # genunix but which might someday become kmods. This must be
99 99 # defined before we include Makefile.uts, or else genunix's build
100 100 # won't be as parallel as we might like.
101 101 #
102 102 NOT_YET_KMODS = $(OLDPTY_OBJS) $(PTY_OBJS) $(VCONS_CONF_OBJS) $(MOD_OBJS)
103 103
104 104 #
105 105 # ----- END OF TRANSITIONAL SECTION -------------------------------------------
106 106 #
107 107 # Include machine independent rules. Note that this does not imply
108 108 # that the resulting module from rules in Makefile.uts is machine
109 109 # independent. Only that the build rules are machine independent.
110 110 #
111 111 include $(UTSBASE)/Makefile.uts
112 112
113 113 #
114 114 # machine specific optimization, override default in Makefile.master
115 115 #
116 116 XARCH_32 = -xarch=v8
117 117 XARCH_64 = -m64
118 118 XARCH = $(XARCH_$(CLASS))
119 119
120 120 COPTIMIZE_32 = -xO3
121 121 COPTIMIZE_64 = -xO3
122 122 COPTIMIZE = $(COPTIMIZE_$(CLASS))
123 123
124 124 CCMODE = -Xa
125 125
126 126 CFLAGS_32 = -xcg92
127 127 CFLAGS_64 = -xchip=ultra $(CCABS32) $(CCREGSYM)
128 128 CFLAGS = $(CFLAGS_$(CLASS))
129 129
130 130 CFLAGS += $(XARCH)
131 131 CFLAGS += $(COPTIMIZE)
132 132 CFLAGS += $(EXTRA_CFLAGS)
133 133 CFLAGS += $(XAOPT)
134 134 CFLAGS += $(INLINES) -D_ASM_INLINES
135 135 CFLAGS += $(CCMODE)
136 136 CFLAGS += $(SPACEFLAG)
137 137 CFLAGS += $(CERRWARN)
138 138 CFLAGS += $(CTF_FLAGS_$(CLASS))
139 139 CFLAGS += $(C99MODE)
140 140 CFLAGS += $(CCUNBOUND)
141 141 CFLAGS += $(CCSTATICSYM)
142 142 CFLAGS += $(CC32BITCALLERS)
143 143 CFLAGS += $(CCNOAUTOINLINE)
144 144 CFLAGS += $(IROPTFLAG)
145 145 CFLAGS += $(CGLOBALSTATIC)
146 146 CFLAGS += -xregs=no%float
147 147 CFLAGS += -xstrconst
148 148 CFLAGS += $(CSOURCEDEBUGFLAGS)
149 149 CFLAGS += $(CUSERFLAGS)
150 150
151 151 ASFLAGS += $(XARCH)
152 152
153 153 LINT_DEFS_32 =
154 154 LINT_DEFS_64 = -m64
155 155 LINT_DEFS += $(LINT_DEFS_$(CLASS))
156 156
157 157 #
158 158 # The following must be defined for all implementations:
159 159 #
160 160 # MODSTUBS: Module stubs source file.
161 161 #
162 162 MODSTUBS = $(UTSBASE)/sparc/ml/modstubs.s
163 163
164 164 #
165 165 # Define the actual specific platforms - obviously none.
166 166 #
167 167 MACHINE_DEFS =
168 168
169 169 #
170 170 # Debugging level
171 171 #
172 172 # Special knowledge of which special debugging options effect which
173 173 # file is used to optimize the build if these flags are changed.
174 174 #
175 175 # XXX: The above could possibly be done for more flags and files, but
176 176 # is left as an experiment to the interested reader. Be forewarned,
177 177 # that excessive use could lead to maintenance difficulties.
178 178 #
179 179 DEBUG_DEFS_OBJ32 =
180 180 DEBUG_DEFS_DBG32 = -DDEBUG
181 181 DEBUG_DEFS_OBJ64 =
182 182 DEBUG_DEFS_DBG64 = -DDEBUG
183 183 DEBUG_DEFS = $(DEBUG_DEFS_$(BUILD_TYPE))
184 184
185 185 DEBUG_COND_OBJ32 = $(POUND_SIGN)
186 186 DEBUG_COND_DBG32 =
187 187 DEBUG_COND_OBJ64 = $(POUND_SIGN)
188 188 DEBUG_COND_DBG64 =
189 189 IF_DEBUG_OBJ = $(DEBUG_COND_$(BUILD_TYPE))$(OBJS_DIR)/
190 190
191 191 $(IF_DEBUG_OBJ)syscall.o := DEBUG_DEFS += -DSYSCALLTRACE
192 192 $(IF_DEBUG_OBJ)clock.o := DEBUG_DEFS += -DKSLICE=1
193 193
194 194 # Comment these out if you don't want dispatcher lock statistics.
195 195
196 196 # $(IF_DEBUG_OBJ)disp_lock.o := DEBUG_DEFS += -DDISP_LOCK_STATS
197 197
198 198 #
199 199 # Collect the preprocessor definitions to be associated with *all*
200 200 # files.
201 201 #
202 202 ALL_DEFS = $(MACHINE_DEFS) $(DEBUG_DEFS) $(OPTION_DEFS)
203 203 #
204 204 #
205 205 # The kernels modules which are "implementation architecture"
206 206 # specific for this machine are enumerated below. Note that most
207 207 # of these modules must exist (in one form or another) for each
208 208 # architecture.
209 209 #
210 210 # Common Drivers (usually pseudo drivers) (/kernel/drv):
211 211 #
|
↓ open down ↓ |
211 lines elided |
↑ open up ↑ |
212 212 DRV_KMODS += aggr arp audio bl blkdev bofi clone cn conskbd consms cpuid
213 213 DRV_KMODS += crypto cryptoadm devinfo dump
214 214 DRV_KMODS += dtrace fasttrap fbt lockstat profile sdt systrace dcpc
215 215 DRV_KMODS += fssnap icmp icmp6 ip ip6 ipnet ipsecah
216 216 DRV_KMODS += ipsecesp iptun iwscn keysock kmdb kstat ksyms llc1
217 217 DRV_KMODS += lofi
218 218 DRV_KMODS += log logindmux kssl mm nca physmem pm poll pool
219 219 DRV_KMODS += pseudo ptc ptm pts ptsl ramdisk random rsm rts sad
220 220 DRV_KMODS += simnet softmac sppp sppptun sy sysevent sysmsg
221 221 DRV_KMODS += spdsock
222 -DRV_KMODS += tcp tcp6 timerfd tl tnf ttymux udp udp6 wc winlock zcons zfd
222 +DRV_KMODS += tcp tcp6 timerfd tl tnf ttymux udp udp6 wc winlock zcons zfs
223 223 DRV_KMODS += ippctl
224 224 DRV_KMODS += dld
225 225 DRV_KMODS += ipd
226 226 DRV_KMODS += ipf
227 227 DRV_KMODS += rpcib
228 228 DRV_KMODS += dlpistub
229 229 DRV_KMODS += vnic
230 230 DRV_KMODS += xge
231 231 DRV_KMODS += rds
232 232 DRV_KMODS += rdsv3
233 233 DRV_KMODS += chxge
234 234 DRV_KMODS += smbsrv
235 235 DRV_KMODS += vscan
236 236 DRV_KMODS += nsmb
237 237 DRV_KMODS += fm
238 238 DRV_KMODS += nulldriver
239 239 DRV_KMODS += bridge trill
240 240 DRV_KMODS += bpf
241 241 DRV_KMODS += dca
242 -DRV_KMODS += inotify
243 242 DRV_KMODS += eventfd
244 243 DRV_KMODS += signalfd
245 -DRV_KMODS += timerfd
244 +DRV_KMODS += inotify
246 245
247 246 #
248 247 # Hardware Drivers in common space
249 248 #
250 249
251 250 DRV_KMODS += afe
252 251 DRV_KMODS += audio1575
253 252 DRV_KMODS += audioens
254 253 DRV_KMODS += audiols
255 254 DRV_KMODS += audiop16x
256 255 DRV_KMODS += audiopci
257 256 DRV_KMODS += audiots
258 257 DRV_KMODS += bnxe
259 258 DRV_KMODS += e1000g
260 259 DRV_KMODS += efe
261 260 DRV_KMODS += hxge
262 261 DRV_KMODS += mxfe
263 262 DRV_KMODS += rge
264 263 DRV_KMODS += rtls
265 264 DRV_KMODS += sfe
266 265 DRV_KMODS += aac
267 266 DRV_KMODS += igb
268 267 DRV_KMODS += ixgbe
269 268 DRV_KMODS += vr
270 269 DRV_KMODS += mr_sas
271 270 DRV_KMODS += yge
272 271
273 272 #
274 273 # Machine Specific Driver Modules (/kernel/drv):
275 274 #
276 275 DRV_KMODS += audiocs
277 276 DRV_KMODS += bge dmfe eri fas hme qfe
278 277 DRV_KMODS += openeepr options sd ses st
279 278 DRV_KMODS += ssd
280 279 DRV_KMODS += ecpp
281 280 DRV_KMODS += hid hubd ehci ohci uhci usb_mid usb_ia scsa2usb usbprn ugen
282 281 DRV_KMODS += usbser usbsacm usbsksp usbsprl
283 282 DRV_KMODS += usb_as usb_ac
284 283 DRV_KMODS += usbskel
285 284 DRV_KMODS += usbvc
286 285 DRV_KMODS += usbftdi
287 286 DRV_KMODS += usbecm
288 287 DRV_KMODS += hci1394 av1394 scsa1394 dcam1394
289 288 DRV_KMODS += sbp2
290 289 DRV_KMODS += ib ibp eibnx eoib rdsib sdp iser daplt hermon tavor sol_ucma sol_uverbs
291 290 DRV_KMODS += sol_umad
292 291 DRV_KMODS += pci_pci pcieb pcieb_bcm
293 292 DRV_KMODS += i8042 kb8042 mouse8042
294 293 DRV_KMODS += fcode
295 294 DRV_KMODS += mpt_sas
296 295 DRV_KMODS += socal
297 296 DRV_KMODS += sgen
298 297 DRV_KMODS += myri10ge
299 298 DRV_KMODS += smp
300 299 DRV_KMODS += dad
301 300 DRV_KMODS += scsi_vhci
302 301 DRV_KMODS += fcp
303 302 DRV_KMODS += fcip
304 303 DRV_KMODS += fcsm
305 304 DRV_KMODS += fp
306 305 DRV_KMODS += qlc
307 306 DRV_KMODS += qlge
308 307 DRV_KMODS += stmf
309 308 DRV_KMODS += stmf_sbd
310 309 DRV_KMODS += fct
311 310 DRV_KMODS += fcoe
312 311 DRV_KMODS += fcoet
313 312 DRV_KMODS += fcoei
314 313 DRV_KMODS += qlt
315 314 DRV_KMODS += iscsit
316 315 DRV_KMODS += pppt
317 316 DRV_KMODS += ncall nsctl sdbc nskern sv
318 317 DRV_KMODS += ii rdc rdcsrv rdcstub
319 318 DRV_KMODS += iscsi
320 319 DRV_KMODS += emlxs
321 320 DRV_KMODS += oce
322 321 DRV_KMODS += srpt
323 322 DRV_KMODS += pmcs
324 323 DRV_KMODS += pmcs8001fw
325 324
326 325 #
327 326 # I/O framework test drivers
328 327 #
329 328 DRV_KMODS += pshot
330 329 DRV_KMODS += gen_drv
331 330 DRV_KMODS += tvhci tphci tclient
332 331 DRV_KMODS += emul64
333 332
334 333 #
335 334 # PCMCIA specific module(s)
336 335 #
337 336 DRV_KMODS += pcs
338 337 MISC_KMODS += busra cardbus dada pcmcia
339 338 DRV_KMODS += pcic
340 339
341 340 # Add lvm
342 341 #
343 342 DRV_KMODS += md
344 343 MISC_KMODS += md_mirror md_stripe md_hotspares md_raid md_trans md_notify
345 344 MISC_KMODS += md_sp
346 345
347 346 #
348 347 # Exec Class Modules (/kernel/exec):
349 348 #
350 349 EXEC_KMODS += aoutexec elfexec intpexec shbinexec javaexec
351 350
352 351 #
353 352 # Scheduling Class Modules (/kernel/sched):
354 353 #
355 354 SCHED_KMODS += RT TS RT_DPTBL TS_DPTBL IA FSS FX FX_DPTBL SDC
356 355
357 356 #
358 357 # File System Modules (/kernel/fs):
359 358 #
360 359 FS_KMODS += dev devfs fdfs fifofs hsfs lofs namefs nfs pcfs tmpfs zfs
361 360 FS_KMODS += zut specfs udfs ufs autofs procfs sockfs mntfs
362 361 FS_KMODS += ctfs objfs sharefs dcfs smbfs bootfs
363 362
364 363 #
365 364 # Streams Modules (/kernel/strmod):
366 365 #
367 366 STRMOD_KMODS += bufmod connld dedump ldterm ms pckt pfmod
368 367 STRMOD_KMODS += pipemod ptem redirmod rpcmod rlmod telmod timod
369 368 STRMOD_KMODS += spppasyn spppcomp
370 369 STRMOD_KMODS += tirdwr ttcompat
371 370 STRMOD_KMODS += usbkbm usbms usbwcm usb_ah
372 371 STRMOD_KMODS += drcompat
373 372 STRMOD_KMODS += cryptmod
374 373 STRMOD_KMODS += vuid3ps2
375 374
376 375 #
377 376 # 'System' Modules (/kernel/sys):
378 377 #
379 378 SYS_KMODS += c2audit
380 379 SYS_KMODS += exacctsys
381 380 SYS_KMODS += inst_sync kaio msgsys semsys shmsys sysacct pipe
382 381 SYS_KMODS += doorfs pset acctctl portfs
383 382
384 383 #
385 384 # 'User' Modules (/kernel/misc):
386 385 #
387 386 MISC_KMODS += ac97
388 387 MISC_KMODS += bignum
389 388 MISC_KMODS += consconfig gld ipc nfs_dlboot nfssrv scsi
390 389 MISC_KMODS += strplumb swapgeneric tlimod
391 390 MISC_KMODS += rpcsec rpcsec_gss kgssapi kmech_dummy
392 391 MISC_KMODS += kmech_krb5
393 392 MISC_KMODS += fssnap_if
394 393 MISC_KMODS += hidparser kbtrans usba usba10 usbs49_fw
395 394 MISC_KMODS += s1394
396 395 MISC_KMODS += hpcsvc pcihp
397 396 MISC_KMODS += rsmops
398 397 MISC_KMODS += kcf
399 398 MISC_KMODS += ksocket
400 399 MISC_KMODS += ibcm
401 400 MISC_KMODS += ibdm
402 401 MISC_KMODS += ibdma
403 402 MISC_KMODS += ibmf
404 403 MISC_KMODS += ibtl
405 404 MISC_KMODS += sol_ofs
406 405 MISC_KMODS += idm
407 406 MISC_KMODS += idmap
408 407 MISC_KMODS += hook
409 408 MISC_KMODS += neti
410 409 MISC_KMODS += ctf
411 410 MISC_KMODS += mac dls
412 411 MISC_KMODS += cmlb
413 412 MISC_KMODS += tem
414 413 MISC_KMODS += pcicfg fcodem fcpci
415 414 MISC_KMODS += scsi_vhci_f_sym scsi_vhci_f_tpgs scsi_vhci_f_asym_sun
416 415 MISC_KMODS += scsi_vhci_f_sym_hds
417 416 MISC_KMODS += scsi_vhci_f_tape scsi_vhci_f_tpgs_tape
418 417 MISC_KMODS += fctl
419 418 MISC_KMODS += emlxs_fw
420 419 MISC_KMODS += qlc_fw_2200
421 420 MISC_KMODS += qlc_fw_2300
422 421 MISC_KMODS += qlc_fw_2400
423 422 MISC_KMODS += qlc_fw_2500
424 423 MISC_KMODS += qlc_fw_6322
425 424 MISC_KMODS += qlc_fw_8100
426 425 MISC_KMODS += spuni
427 426 MISC_KMODS += mii
428 427
429 428 MISC_KMODS += klmmod klmops
430 429
431 430 #
432 431 # Software Cryptographic Providers (/kernel/crypto):
433 432 #
434 433 CRYPTO_KMODS += aes
435 434 CRYPTO_KMODS += arcfour
436 435 CRYPTO_KMODS += blowfish
437 436 CRYPTO_KMODS += des
438 437 CRYPTO_KMODS += ecc
439 438 CRYPTO_KMODS += edonr
440 439 CRYPTO_KMODS += md4
441 440 CRYPTO_KMODS += md5
442 441 CRYPTO_KMODS += rsa
443 442 CRYPTO_KMODS += sha1
444 443 CRYPTO_KMODS += sha2
445 444 CRYPTO_KMODS += skein
446 445 CRYPTO_KMODS += swrand
447 446
448 447 #
449 448 # IP Policy Modules (/kernel/ipp):
450 449 #
451 450 IPP_KMODS += dlcosmk
452 451 IPP_KMODS += flowacct
453 452 IPP_KMODS += ipgpc
454 453 IPP_KMODS += dscpmk
455 454 IPP_KMODS += tokenmt
456 455 IPP_KMODS += tswtclmt
457 456
458 457 #
459 458 # 'Dacf' modules (/kernel/dacf)
460 459 DACF_KMODS += consconfig_dacf
461 460
462 461 #
463 462 # SVVS Testing Modules (/kernel/strmod):
464 463 #
465 464 # These are streams and driver modules which are not to be
466 465 # delivered with a released system. However, during development
467 466 # it is convenient to build and install the SVVS kernel modules.
468 467 #
469 468 SVVS_KMODS += lmodb lmode lmodr lmodt svvslo tidg tivc tmux
470 469
471 470 #
472 471 # Modules eXcluded from the product:
473 472 #
474 473 XMODS +=
475 474
476 475 #
477 476 # 'Dacf' Modules (/kernel/dacf):
478 477 #
479 478 DACF_KMODS += net_dacf
480 479
481 480 #
482 481 # MAC-Type Plugin Modules (/kernel/mac)
483 482 #
484 483 MAC_KMODS += mac_6to4
485 484 MAC_KMODS += mac_ether
486 485 MAC_KMODS += mac_ipv4
487 486 MAC_KMODS += mac_ipv6
488 487 MAC_KMODS += mac_wifi
|
↓ open down ↓ |
233 lines elided |
↑ open up ↑ |
489 488 MAC_KMODS += mac_ib
490 489
491 490 #
492 491 # socketmod (kernel/socketmod)
493 492 #
494 493 SOCKET_KMODS += sockpfp
495 494 SOCKET_KMODS += socksctp
496 495 SOCKET_KMODS += socksdp
497 496 SOCKET_KMODS += sockrds
498 497 SOCKET_KMODS += ksslf
498 +SOCKET_KMODS += httpfilt
499 499 SOCKET_KMODS += datafilt
500 500
501 501 #
502 502 # kiconv modules (/kernel/kiconv):
503 503 #
504 504 KICONV_KMODS += kiconv_emea kiconv_ja kiconv_ko kiconv_sc kiconv_tc
505 505
506 506 #
507 507 # Ensure that the variable member of the cpu_t (cpu_m) is defined
508 508 # for the lint builds so as not to cause lint errors during the
509 509 # global cross check.
510 510 #
511 511 $(LINTFLAGSUPPRESS)LINTFLAGS += -D_MACHDEP -I$(UTSBASE)/sun4 \
512 512 -I$(UTSBASE)/sun4u -I$(UTSBASE)/sfmmu
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX