config 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  1. #!/bin/sh
  2. #
  3. # Kernel config script for OS/161.
  4. #
  5. # Usage: ./config conf-name
  6. #
  7. # WARNING! IF YOU JUST RUN "config" INSTEAD OF "./config" YOU WILL
  8. # PROBABLY GET THE HOST SYSTEM'S KERNEL CONFIG INSTEAD OF THIS ONE,
  9. # WHICH WILL CAUSE WEIRD THINGS TO HAPPEN. DON'T DO IT.
  10. #
  11. #
  12. # Recognized directives:
  13. #
  14. # file <filename> use source file
  15. # debug turn on debug info
  16. # defoption <sym> define an option
  17. # optfile <sym> <file> if option <sym> is enabled, use file <file>
  18. # optofffile <sym> <file> if option <sym> is disabled, use file <file>
  19. # defdevice <dev> <file> define a device
  20. # defattach <dev> <bus> <file>
  21. # define an attachment for a device to a bus
  22. # pseudoattach <dev> define a pseudo-attachment for a device
  23. #
  24. # options <sym> enable an option
  25. # device <dev> [at <bus>] enable a particular device [on a particular bus]
  26. #
  27. # include <filename> get additional directives from another file
  28. #
  29. # Filenames are relative to the top of the kernel tree.
  30. #
  31. # The comment character is '#'.
  32. #
  33. # The idea is that the first group of directives is used to set up a
  34. # static description of all possible configurations for each supported
  35. # architecture. Then a kernel config file uses the second group of
  36. # directives to specify a particular configuration. Then this script
  37. # is used to first check that the configuration is one of the possible
  38. # ones, and then to set up the compile directory, makefiles, and
  39. # associated material necessary to actually build that configuration.
  40. #
  41. # Further documentation is at the top of conf.kern.
  42. #
  43. #
  44. # Make sure we're in the right place.
  45. #
  46. if [ ! -d ../startup ]; then
  47. echo "$0: Run me from src/kern/conf"
  48. exit 1
  49. fi
  50. ########################################
  51. #
  52. # 1. Get configuration name and config file.
  53. #
  54. CONFNAME=$1
  55. if [ "x$CONFNAME" = x ]; then
  56. echo "Usage: $0 CONFIG-NAME"
  57. exit 1
  58. fi
  59. FOO=`echo $CONFNAME | tr -d 'a-zA-Z0-9_-'`
  60. if [ "x$FOO" != x ]; then
  61. echo "Illegal configuration name $CONFNAME"
  62. exit 1
  63. fi
  64. if [ ! -f $CONFNAME ]; then
  65. echo "$0: $CONFNAME not found"
  66. exit 1
  67. fi
  68. echo "Configuration $CONFNAME"
  69. COMPILEDIR="../compile/$CONFNAME"
  70. ########################################
  71. #
  72. # 2. Process includes.
  73. # Also strip comments.
  74. # Simultaneously, do a basic syntax check.
  75. #
  76. # For an introduction to awk, see
  77. # http://www.hcs.harvard.edu/~dholland/computers/awk.html
  78. #
  79. CONFTMP=.conftmp
  80. rm -f $CONFTMP
  81. echo "$CONFNAME" $CONFTMP | awk '
  82. BEGIN {
  83. #
  84. # Initialize list of directives and required numbers of words for each.
  85. #
  86. nfields["include"] = 2;
  87. nfields["file"] = 2;
  88. nfields["debug"] = 1;
  89. nfields["defoption"] = 2;
  90. nfields["optfile"] = 3;
  91. nfields["optofffile"] = 3;
  92. nfields["defdevice"] = 3;
  93. nfields["defattach"] = 4;
  94. nfields["pseudoattach"] = 2;
  95. nfields["options"] = 2;
  96. nfields["device"] = 4; # actually 2 or 4, handled specially
  97. #
  98. # Directives that can be made machine-dependent with "machine"
  99. # or "platform".
  100. #
  101. okmd["file"] = 1;
  102. okmd["optfile"] = 1;
  103. okmd["optofffile"] = 1;
  104. }
  105. function doinclude(file, lineno) {
  106. #
  107. # Include a file.
  108. #
  109. # lineno is a local.
  110. #
  111. # Read lines and hand them off recursively to processline().
  112. #
  113. lineno = 1;
  114. while (getline < file) {
  115. if (ERRNO) {
  116. printf "%s: %s\n", file, ERRNO;
  117. exit(1);
  118. }
  119. processline(file, lineno);
  120. lineno++;
  121. }
  122. }
  123. function processline(filename, lineno) {
  124. #
  125. # Handle a single config line.
  126. #
  127. # Strip comments.
  128. sub("#.*", "", $0);
  129. # Ignore blank lines.
  130. if (NF==0) return;
  131. direct = $1;
  132. foundfields = NF;
  133. if (direct == "machine" && NF > 2 && okmd[$3]) {
  134. # machine mips file ...
  135. direct = $3;
  136. foundfields -= 2;
  137. }
  138. else if (direct == "platform" && NF > 2 && okmd[$3]) {
  139. # platform sys161 file ...
  140. direct = $3;
  141. foundfields -= 2;
  142. }
  143. # Syntax check: reject unknown directives
  144. if (!nfields[direct]) {
  145. printf "%s: %d: Unknown directive %s\n", filename, lineno, direct;
  146. exit(1);
  147. }
  148. # Syntax check: require correct # of args.
  149. if (direct=="device") {
  150. # special case - device directive can have 2 or 4 words
  151. if ((NF!=2 && NF!=4) || (NF==4 && $3!="at")) {
  152. msg = sprintf("%s: Invalid arguments", direct);
  153. printf "%s: %d: %s\n", filename, lineno, msg;
  154. exit(1);
  155. }
  156. }
  157. else if (nfields[direct]!=foundfields) {
  158. printf "%s: %d: %s: Invalid arguments\n", filename, lineno, direct;
  159. exit(1);
  160. }
  161. # Now actually process the directives we need at this stage - which
  162. # is only "include". Handle includes.
  163. if (direct == "include") {
  164. doinclude("../" $2);
  165. }
  166. else {
  167. print >> outfile;
  168. }
  169. }
  170. #
  171. # Code called for lines input on stdin.
  172. # There is only one - the one generated above with echo, which
  173. # gives us the names of the input and output files to use.
  174. #
  175. {
  176. outfile = $2;
  177. doinclude($1);
  178. }
  179. ' || exit 1
  180. ########################################
  181. #
  182. # 3. Create compile dir.
  183. #
  184. if [ ! -d "$COMPILEDIR" ]; then
  185. mkdir $COMPILEDIR
  186. fi
  187. echo -n 'Generating files...'
  188. ########################################
  189. #
  190. # 4. Process device attachments into $CONFTMP.attach.
  191. # Also add device/attachment files to $CONFTMP.files.
  192. #
  193. rm -f $CONFTMP.files
  194. rm -f $CONFTMP.attach
  195. awk < $CONFTMP '
  196. #
  197. # Function to grab the "0" off "le0" or the "*" off "wd*".
  198. #
  199. function getunit(invalmsg, d, u, tmp) {
  200. u = d;
  201. sub("^[a-zA-Z_]*", "", u);
  202. if (u!="*") {
  203. tmp = u;
  204. sub("[0-9]*", "", tmp);
  205. if (tmp!="") {
  206. printf "\n%s: Invalid device/unit specification\n", invalmsg;
  207. exit(1);
  208. }
  209. }
  210. return u;
  211. }
  212. #
  213. # Function to grab the "le" off "le0" or the "wd" off "wd*".
  214. #
  215. function getbase(invalmsg, d, base) {
  216. base = d;
  217. sub("[\\*0-9]*$", "", base);
  218. if (!use[base]) {
  219. printf "\n%s: No such device\n", invalmsg;
  220. exit(1);
  221. }
  222. return base;
  223. }
  224. #
  225. # Routine invoked for "defdevice" directive lines.
  226. #
  227. $1=="defdevice" {
  228. dev = $2;
  229. file = $3;
  230. # Check for illegal characters in device name
  231. # (must be legal C symbol, and at this point must not have unit number)
  232. tmp = dev;
  233. sub("[a-zA-Z_]*", "", tmp);
  234. if (tmp!="") {
  235. printf "\ndefdevice %s: Illegal device name\n", dev;
  236. exit(1);
  237. }
  238. # Device must not have been already defined.
  239. if (use[dev]) {
  240. printf "\ndefdevice %s: %s already exists\n", dev, dev;
  241. exit(1);
  242. }
  243. # Note that it exists, but is not in use, and remember the
  244. # source file for later.
  245. use[dev] = "no";
  246. files[dev] = file;
  247. }
  248. #
  249. # Routine called for "defattach" directive lines.
  250. #
  251. $1=="defattach" {
  252. dev = $2;
  253. bus = $3;
  254. file = $4;
  255. # Even though we do not use basebus, busunit, or devunit,
  256. # call the routines to compute them, because they check the
  257. # syntax.
  258. devmsg = "defattach: device " dev;
  259. devunit = getunit(devmsg, dev);
  260. basedev = getbase(devmsg, dev);
  261. busmsg = "defattach: bus " bus;
  262. busunit = getunit(busmsg, bus);
  263. basebus = getbase(busmsg, bus);
  264. if (pseudo[basedev]) {
  265. printf "\n%s: Already declared pseudoattach\n", devmsg;
  266. exit(1);
  267. }
  268. # The attachment is the pair of bus and device.
  269. # We remember the specific names, including the unit numbers.
  270. # This is because "le* at sbus*" is different from "le0 at sbus0"
  271. # - the former allows le0 to be at sbus1, allows le1, etc.
  272. attachment = bus "." dev;
  273. attach[attachment] = "no";
  274. files[attachment] = file;
  275. # Remember that attachments are defined for this device. If
  276. # attachments are defined, when the device is turned on later
  277. # an attachment must be specified.
  278. attachable[basedev] = 1;
  279. }
  280. #
  281. # Routine called for "pseudoattach" directive lines.
  282. #
  283. $1=="pseudoattach" {
  284. dev = $2;
  285. devmsg = "pseudoattach: device " dev;
  286. devunit = getunit(devmsg, dev);
  287. basedev = getbase(devmsg, dev);
  288. if (attachable[basedev]) {
  289. printf "\n%s: Attachments already declared\n", devmsg;
  290. exit(1);
  291. }
  292. # Remember that this device is a pseudo-device.
  293. pseudo[basedev] = 1;
  294. }
  295. #
  296. # Helper function for the "device" code.
  297. #
  298. function tryattach(combo) {
  299. if (!attachok && attach[combo]) {
  300. # This attachment is defined. Note to compile it in, and report
  301. # success.
  302. attach[combo] = "yes";
  303. attachok = 1;
  304. }
  305. }
  306. #
  307. # Routine called for "device" directive lines.
  308. #
  309. $1=="device" {
  310. dev = $2;
  311. if (NF==4) {
  312. devmsg = "device: " dev " at " $4;
  313. }
  314. else {
  315. devmsg = "device: device " dev;
  316. }
  317. devunit = getunit(devmsg, dev);
  318. basedev = getbase(devmsg, dev);
  319. gendev = basedev "*";
  320. if (NF==4) {
  321. #
  322. # The longer form, with an attachment ("bus").
  323. #
  324. bus = $4;
  325. busmsg = "device: " dev " at " bus ": " bus;
  326. busunit = getunit(busmsg, bus);
  327. basebus = getbase(busmsg, bus);
  328. genbus = basebus "*";
  329. if (use[basebus]!="yes") {
  330. printf "\ndevice: bus %s: Bus device is not enabled\n", bus;
  331. exit(1);
  332. }
  333. # If the line was "le0 at sbus0", we try to attach it using
  334. # the following attachments:
  335. # First, the exact thing that was requested:
  336. # sbus0.le0 (le0 at sbus0)
  337. # Second, for any such device on that bus:
  338. # sbus*.le0 (le0 at sbus*)
  339. # Third, for that device on any such bus:
  340. # sbus0.le* (le* at sbus0)
  341. # Fourth, for any such device on any such bus:
  342. # sbus*.le* (le* at sbus*)
  343. #
  344. # If the line was "le* at sbus0", some of these will be
  345. # redundant, but that is ok.
  346. attachok = 0;
  347. tryattach(bus "." dev);
  348. tryattach(bus "." gendev);
  349. tryattach(genbus "." dev);
  350. tryattach(genbus "." gendev);
  351. if (!attachok) {
  352. # No matching attachment found.
  353. printf "\ndevice: %s at %s: Undefined attachment\n", dev, bus;
  354. exit(1);
  355. }
  356. devattach = sprintf("%s %s", basedev, devunit);
  357. baseattach = sprintf("%s %s", basebus, busunit);
  358. printf "attach %s at %s\n", devattach, baseattach >> attachfile;
  359. }
  360. else {
  361. # No bus specified to attach the device to (really, to find the
  362. # device attached on.) This is only legal if no attachments
  363. # at all were defined for the device, which is the case if the
  364. # device is in fact not attached to anything else (like the main
  365. # system bus, or a device like /dev/null that has no hardware.)
  366. # The opposite check to this is not required in the
  367. # preceding section because no attachment can be found if
  368. # attachable[basedev] is false.
  369. if (attachable[basedev]) {
  370. printf "\ndevice %s: attachment required\n", dev;
  371. exit(1);
  372. }
  373. if (pseudo[basedev]) {
  374. if (devunit=="*") {
  375. printf "\n%s: May not use wildcard units here\n", devmsg;
  376. exit(1);
  377. }
  378. printf "pseudo %s %s\n", basedev, devunit >> attachfile;
  379. }
  380. else {
  381. printf "noattach %s\n", basedev >> attachfile;
  382. }
  383. }
  384. use[basedev] = "yes";
  385. }
  386. #
  387. # Routine invoked when we have seen all the input.
  388. #
  389. END {
  390. # Print out the source filenames for the devices and attachments
  391. # we are using.
  392. for (dev in use) {
  393. if (use[dev]=="yes") {
  394. printf "* * %s\n", files[dev] >> filelistfile;
  395. }
  396. }
  397. for (att in attach) {
  398. if (attach[att]=="yes") {
  399. printf "* * %s\n", files[att] >> filelistfile;
  400. }
  401. }
  402. }
  403. ' "attachfile=$CONFTMP.attach" "filelistfile=$CONFTMP.files" || exit 1
  404. ########################################
  405. #
  406. # 5. Process options.
  407. #
  408. awk < $CONFTMP '
  409. #
  410. # Routine for a defoption line.
  411. #
  412. $1=="defoption" {
  413. opt = $2;
  414. options[opt] = "no";
  415. }
  416. #
  417. # Routine for an optfile line.
  418. #
  419. $1=="optfile" || (($1=="machine" || $1=="platform") && $3=="optfile") {
  420. if ($1 == "optfile") {
  421. opt = $2;
  422. file = $3;
  423. platform = "*";
  424. machine = "*";
  425. }
  426. else {
  427. if ($1=="machine") {
  428. platform = "*";
  429. machine = $2;
  430. }
  431. else {
  432. platform = $2;
  433. machine = "*";
  434. }
  435. opt = $4;
  436. file = $5;
  437. }
  438. if (!options[opt]) {
  439. printf "\noptfile %s %s: No such option %s\n", opt, file, opt;
  440. exit(1);
  441. }
  442. controllers[file] = opt;
  443. platforms[file] = platform;
  444. machines[file] = machine;
  445. }
  446. #
  447. # Routine for an optofffile line.
  448. #
  449. $1=="optofffile" || (($1=="machine" || $1=="platform") &&$3=="optofffile"){
  450. if ($1 == "optofffile") {
  451. opt = $2;
  452. file = $3;
  453. platform = "*";
  454. machine = "*";
  455. }
  456. else {
  457. if ($1=="machine") {
  458. platform = "*";
  459. machine = $2;
  460. }
  461. else {
  462. platform = $2;
  463. machine = "*";
  464. }
  465. opt = $4;
  466. file = $5;
  467. }
  468. if (!options[opt]) {
  469. printf "\noptofffile %s %s: No such option %s\n", opt, file, opt;
  470. exit(1);
  471. }
  472. offcontrollers[file] = opt;
  473. platforms[file] = platform;
  474. machines[file] = machine;
  475. }
  476. #
  477. # Routine for an options line.
  478. #
  479. $1=="options" {
  480. opt = $2;
  481. if (!options[$2]) {
  482. printf "\noptions %s: No such option\n", opt;
  483. exit(1);
  484. }
  485. options[$2] = "yes";
  486. }
  487. #
  488. # Routine invoked when we have seen everything.
  489. #
  490. END {
  491. #
  492. # First, add any files to the list of sources we are building.
  493. #
  494. for (file in controllers) {
  495. if (options[controllers[file]]=="yes") {
  496. line = sprintf("%s %s %s",
  497. platforms[file], machines[file], file);
  498. printf "%s\n", line >> filelistfile;
  499. }
  500. }
  501. for (file in offcontrollers) {
  502. if (options[offcontrollers[file]]=="no") {
  503. line = sprintf("%s %s %s",
  504. platforms[file], machines[file], file);
  505. printf "%s\n", line >> filelistfile;
  506. }
  507. }
  508. close(filelistfile);
  509. #
  510. # Now, generate the .h file for every option
  511. # (both the ones that are on and the ones that are off)
  512. #
  513. for (opt in options) {
  514. realfile = compiledir "/opt-" opt ".h";
  515. file = realfile ".new";
  516. sym = toupper(opt);
  517. printf "/* Automatically generated; do not edit */\n" > file;
  518. printf "#ifndef _OPT_%s_H_\n", sym >> file;
  519. printf "#define _OPT_%s_H_\n", sym >> file;
  520. val = options[opt]=="yes" ? 1 : 0;
  521. printf "#define OPT_%s %d\n", sym, val >> file;
  522. printf "#endif /* _OPT_%s_H_ */\n", sym >> file;
  523. close(file);
  524. }
  525. }
  526. ' "compiledir=$COMPILEDIR" "filelistfile=$CONFTMP.files" || exit 1
  527. # Avoid changing the actual headers if they aren't different, so as to
  528. # reduce unnecessary recompiles.
  529. (
  530. cd $COMPILEDIR
  531. for NF in opt-*.h.new; do
  532. OF=`echo $NF | sed 's/\.new$//'`
  533. if diff $OF $NF >/dev/null 2>&1; then
  534. rm -f $NF # unchanged
  535. else
  536. mv -f $NF $OF # it changed
  537. fi
  538. echo -n " $OF"
  539. done
  540. )
  541. ########################################
  542. #
  543. # 6. Add in the unconditional files.
  544. #
  545. awk < $CONFTMP '
  546. $1=="file" {
  547. printf "* * %s\n", $2 >> filelistfile;
  548. }
  549. $1=="machine" && $3=="file" {
  550. printf "* %s %s\n", $2, $4 >> filelistfile;
  551. }
  552. $1=="platform" && $3=="file" {
  553. printf "%s * %s\n", $2, $4 >> filelistfile;
  554. }
  555. ' "filelistfile=$CONFTMP.files" || exit 1
  556. #
  557. # autoconf.c (which we generate further down) is always compiled in but
  558. # is not in the list yet. Note that the path to it is where we are about
  559. # to put it: it lives in the build directory, because it's part of a
  560. # particular build.
  561. #
  562. echo "* * compile/$CONFNAME/autoconf.c" >> $CONFTMP.files
  563. ########################################
  564. #
  565. # 7. We now have the compile file list.
  566. # Generate files.mk.
  567. #
  568. #
  569. # Validate list first.
  570. #
  571. # We allow C++ files, because the makefile rules we generate are
  572. # sufficient to compile them. However, some low-level kernel hacking
  573. # will be needed to actually use C++ in OS/161.
  574. #
  575. awk < $CONFTMP.files '
  576. /\.cc$/ { next; }
  577. /\.cpp$/ { next; }
  578. /\.C$/ { next; }
  579. /\.c$/ { next; }
  580. #/\.l$/ { next; } # will require some makefile hacking to make work
  581. #/\.y$/ { next; } # will require some makefile hacking to make work
  582. /\.S$/ { next; }
  583. /\.o$/ { next; }
  584. {
  585. printf "\n%s: Unrecognized source file type\n", $1;
  586. exit(1);
  587. }
  588. ' || exit 1;
  589. #
  590. # Do it.
  591. # Generate a make rule for each file.
  592. #
  593. sort < $CONFTMP.files | awk '
  594. BEGIN {
  595. printf "# Automatically generated by config; do not edit\n";
  596. }
  597. {
  598. platform = $1;
  599. machine = $2;
  600. file = $3;
  601. # get basename
  602. basename = file;
  603. sub(".*/", "", basename);
  604. # get extension
  605. ext = basename;
  606. sub(".*\\.", "", ext);
  607. sub("\\.[^\\.]*$", "", basename);
  608. if (file ~ "^\\.\\./") {
  609. sub("^...", "", file);
  610. path = "$(TOP)/" file;
  611. }
  612. else {
  613. path = "$(KTOP)/" file;
  614. }
  615. #
  616. # For now a file cannot be both platform-dependent and
  617. # machine-dependent, so this sequence of tests is enough.
  618. #
  619. if (platform != "*") {
  620. printf "SRCS.PLATFORM.%s+=%s\n", platform, path;
  621. }
  622. else if (machine != "*") {
  623. printf "SRCS.MACHINE.%s+=%s\n", machine, path;
  624. }
  625. else {
  626. printf "SRCS+=%s\n", path;
  627. }
  628. }
  629. ' > $COMPILEDIR/files.mk
  630. rm -f $CONFTMP.files
  631. echo -n ' files.mk'
  632. ########################################
  633. #
  634. # 8. (reserved)
  635. #
  636. ########################################
  637. #
  638. # 9. Generate Makefile
  639. #
  640. (
  641. echo "# Automatically generated by config; do not edit."
  642. echo "#"
  643. echo
  644. echo '# Top of the kernel tree'
  645. echo 'KTOP=../..'
  646. echo '# Top of the whole tree'
  647. echo 'TOP=$(KTOP)/..'
  648. echo '# Debug vs. optimize'
  649. awk < $CONFTMP '
  650. # Default: optimize.
  651. BEGIN { debugflags="-O2"; }
  652. $1=="debug" {
  653. debugflags="-g";
  654. }
  655. END {
  656. printf "KDEBUG=%s\n", debugflags;
  657. }
  658. '
  659. echo '# Name of the kernel config file'
  660. echo "CONFNAME=$CONFNAME"
  661. echo
  662. echo '.include "$(TOP)/mk/os161.config.mk"'
  663. echo '.include "files.mk"'
  664. echo '.include "$(TOP)/mk/os161.kernel.mk"'
  665. ) > $COMPILEDIR/Makefile || exit 1
  666. echo -n ' Makefile'
  667. ########################################
  668. #
  669. # 10. (reserved)
  670. #
  671. ########################################
  672. #
  673. # 11. Process attachment list.
  674. # Generate autoconf.[ch].
  675. #
  676. ACHREAL=$COMPILEDIR/autoconf.h
  677. ACH=$COMPILEDIR/autoconf.h.new
  678. ACC=$COMPILEDIR/autoconf.c
  679. echo '/* Automatically generated; do not edit */' > $ACH
  680. echo '/* Automatically generated; do not edit */' > $ACC
  681. echo '#ifndef _AUTOCONF_H_' >> $ACH
  682. echo '#define _AUTOCONF_H_' >> $ACH
  683. #
  684. # first, declare struct foo_softc for all devices foo.
  685. #
  686. echo >> $ACH
  687. awk < $CONFTMP.attach '{ printf "struct %s_softc;\n", $2 }' >> $ACH
  688. #
  689. # second, declare the autoconf_foo functions for unattached devices.
  690. #
  691. # The autoconf_foo functions for attached devices are file-static
  692. # in autoconf.c.
  693. #
  694. echo >> $ACH
  695. awk < $CONFTMP.attach '$1=="noattach" { print $2 }' | sort -u | awk '
  696. {
  697. printf "void autoconf_%s(struct %s_softc *dev, int unit);\n", $1, $1;
  698. }
  699. ' >> $ACH
  700. #
  701. # third, declare the attach functions.
  702. #
  703. echo >> $ACH
  704. awk < $CONFTMP.attach '
  705. $1=="attach" {
  706. dev = $2;
  707. bus = $5;
  708. f = sprintf("struct %s_softc *attach_%s_to_%s", dev, dev, bus);
  709. printf "%s(int devunit, struct %s_softc *bus);\n", f, bus;
  710. }
  711. $1=="pseudo" {
  712. dev = $2;
  713. printf "struct %s_softc *pseudoattach_%s(int devunit);\n", dev, dev;
  714. }
  715. ' >> $ACH
  716. #
  717. # fourth, declare the config functions.
  718. #
  719. echo >> $ACH
  720. awk < $CONFTMP.attach '
  721. $1=="attach" {
  722. dev = $2;
  723. printf "int config_%s(struct %s_softc *dev, int unit);\n", dev, dev;
  724. }
  725. ' >> $ACH
  726. #
  727. # Declare pseudoconfig()
  728. #
  729. echo >> $ACH
  730. echo 'void pseudoconfig(void);' >> $ACH
  731. echo >> $ACH
  732. #
  733. # Done with the header file.
  734. #
  735. echo '#endif /* _AUTOCONF_H_ */' >> $ACH
  736. #
  737. # Avoid changing the actual autoconf.h if it's not different, so as to
  738. # reduce unnecessary recompiles.
  739. #
  740. if diff $ACHREAL $ACH >/dev/null 2>&1; then
  741. rm -f $ACH # unchanged
  742. else
  743. mv -f $ACH $ACHREAL # it changed
  744. fi
  745. echo -n ' autoconf.h'
  746. #
  747. # now, autoconf.c
  748. #
  749. echo '#include <types.h>' >> $ACC
  750. echo '#include <lib.h>' >> $ACC
  751. echo '#include "autoconf.h"' >> $ACC
  752. #
  753. # first, declare the static autoconf_foo functions and the nextunit_foo vars
  754. #
  755. echo >> $ACC
  756. awk < $CONFTMP.attach '$1=="attach" || $1=="pseudo" { print $2 }' | sort -u |\
  757. awk '
  758. {
  759. printf "static void autoconf_%s(struct %s_softc *, int);\n", $1, $1;
  760. }
  761. ' >> $ACC
  762. awk < $CONFTMP.attach '$1=="attach" { print $2 }' | sort -u | awk '
  763. {
  764. printf "static int nextunit_%s;\n", $1;
  765. }
  766. ' >> $ACC
  767. echo >> $ACC
  768. #
  769. # Now generate the tryattach_ functions.
  770. #
  771. awk < $CONFTMP.attach '
  772. $1=="attach" {
  773. dev = $2;
  774. bus = $5;
  775. printf "static\n";
  776. printf "int\n";
  777. printf "tryattach_%s_to_%s", dev, bus;
  778. printf "(int devunit, struct %s_softc *bus, int busunit)\n", bus;
  779. printf "{\n";
  780. printf "\tstruct %s_softc *dev;\n", dev;
  781. printf "\tint result;\n", dev;
  782. printf "\n";
  783. printf "\tdev = attach_%s_to_%s(devunit, bus);\n", dev, bus;
  784. printf "\tif (dev==NULL) {\n";
  785. printf "\t\treturn -1;\n";
  786. printf "\t}\n";
  787. printf "\tkprintf(\"%s%%d at %s%%d\", devunit, busunit);\n", dev, bus;
  788. printf "\tresult = config_%s(dev, devunit);\n", dev;
  789. printf "\tif (result != 0) {\n";
  790. printf "\t\tkprintf(\": %%s\\n\", strerror(result));\n";
  791. # Note: we leak the device softc instead of trying
  792. # to clean it up.
  793. printf "\t\t/* should really clean up dev */\n";
  794. printf "\t\treturn result;\n";
  795. printf "\t}\n";
  796. printf "\tkprintf(\"\\n\");\n";
  797. printf "\tnextunit_%s = devunit+1;\n", dev;
  798. printf "\tautoconf_%s(dev, devunit);\n", dev;
  799. printf "\treturn 0;\n";
  800. printf "}\n";
  801. printf "\n";
  802. }
  803. ' >> $ACC
  804. echo >> $ACC
  805. #
  806. # Now comes the tricky part, actually writing those autoconf
  807. # functions. We need one for every device. In each one, there needs
  808. # to be a probe section for each line in $CONFTMP.attach in which that
  809. # device appears on the *right hand* (bus) side.
  810. #
  811. awk < $CONFTMP.attach '
  812. BEGIN { nlines=0; npseudo=0; }
  813. $1=="attach" {
  814. devs[nlines] = $2;
  815. devunits[nlines] = $3;
  816. buses[nlines] = $5;
  817. busunits[nlines] = $6;
  818. alldevs[$2] = 1;
  819. nlines++;
  820. }
  821. $1=="noattach" {
  822. alldevs[$2] = 0;
  823. }
  824. $1=="pseudo" {
  825. alldevs[$2] = 0;
  826. pseudodevs[npseudo] = $2;
  827. pseudounits[npseudo] = $3;
  828. npseudo++;
  829. }
  830. function genprobe(dev, devunit, bus, busunit) {
  831. tryfunc = sprintf("tryattach_%s_to_%s", dev, bus);
  832. if (busunit!="*") {
  833. printf "\tif (busunit==%d) {\n", busunit;
  834. }
  835. else {
  836. printf "\t{\n";
  837. }
  838. if (devunit!="*") {
  839. printf "\t\tif (nextunit_%s <= %d) {\n", dev, devunit;
  840. printf "\t\t\t%s(%d, bus, busunit);\n", tryfunc, devunit;
  841. printf "\t\t}\n";
  842. }
  843. else {
  844. printf "\t\tint result, devunit=nextunit_%s;\n", dev;
  845. printf "\t\tdo {\n";
  846. printf "\t\t\tresult = %s(devunit, bus, busunit);\n", tryfunc;
  847. printf "\t\t\tdevunit++;\n";
  848. printf "\t\t} while (result==0);\n";
  849. }
  850. printf "\t}\n";
  851. }
  852. END {
  853. for (bus in alldevs) {
  854. softc = sprintf("struct %s_softc", bus);
  855. if (alldevs[bus]) printf "static\n";
  856. printf "void\n";
  857. printf "autoconf_%s(%s *bus, int busunit)\n", bus, softc;
  858. printf "{\n";
  859. printf "\t(void)bus; (void)busunit;\n";
  860. for (i=0; i<nlines; i++) {
  861. if (buses[i]==bus) {
  862. genprobe(devs[i], devunits[i], buses[i], busunits[i]);
  863. }
  864. }
  865. printf "}\n\n";
  866. }
  867. printf "void\n";
  868. printf "pseudoconfig(void)\n";
  869. printf "{\n";
  870. for (i=0; i<npseudo; i++) {
  871. dev = pseudodevs[i];
  872. unit = pseudounits[i];
  873. printf "\t{\n";
  874. printf "\t\tstruct %s_softc *s;\n", dev;
  875. printf "\t\t\n";
  876. printf "\t\ts = pseudoattach_%s(%s);\n", dev, unit;
  877. printf "\t\tif (s!=NULL) {\n";
  878. printf "\t\t\tkprintf(\"%s%d (virtual)\\n\");\n", dev, unit;
  879. printf "\t\t\tautoconf_%s(s, %s);\n", dev, unit;
  880. printf "\t\t}\n";
  881. printf "\t}\n";
  882. }
  883. printf "}\n\n";
  884. }
  885. ' >> $ACC
  886. echo -n ' autoconf.c'
  887. rm -f $CONFTMP $CONFTMP.attach
  888. ########################################
  889. #
  890. # Done.
  891. #
  892. echo
  893. echo "Configuration in ../compile/$CONFNAME done"
  894. echo "Remember to bmake depend"