Browse Source

Merged mcb30-realmode-redesign back to HEAD

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
0ff80b477d
100 changed files with 4876 additions and 4254 deletions
  1. 3
    2
      src/.cvsignore
  2. 131
    24
      src/Config
  3. 0
    133
      src/Families
  4. 141
    11
      src/Makefile
  5. 0
    18
      src/Makefile-armnommu
  6. 0
    18
      src/Makefile-e1
  7. 0
    18
      src/Makefile-i386
  8. 0
    18
      src/Makefile-ia64
  9. 375
    0
      src/Makefile.housekeeping
  10. 0
    445
      src/Makefile.main
  11. 4
    2
      src/arch/armnommu/core/arm_timer.c
  12. 4
    1
      src/arch/e1/core/e1_timer.c
  13. 5
    0
      src/arch/i386/Config
  14. 124
    369
      src/arch/i386/Makefile
  15. 197
    0
      src/arch/i386/README.i386
  16. 0
    1
      src/arch/i386/core/callbacks.c
  17. 4
    0
      src/arch/i386/core/cpu.c
  18. 1
    0
      src/arch/i386/core/elf.c
  19. 83
    25
      src/arch/i386/core/hooks.c
  20. 5
    2
      src/arch/i386/core/i386_timer.c
  21. 0
    305
      src/arch/i386/core/init.S
  22. 27
    0
      src/arch/i386/core/pxe_callbacks.c
  23. 21
    129
      src/arch/i386/core/realmode.c
  24. 0
    564
      src/arch/i386/core/realmode_asm.S
  25. 40
    0
      src/arch/i386/core/setjmp.S
  26. 158
    0
      src/arch/i386/core/setup.S
  27. 0
    285
      src/arch/i386/core/start16.S
  28. 3
    450
      src/arch/i386/core/start32.S
  29. 0
    1
      src/arch/i386/core/tagged_loader.c
  30. 15
    7
      src/arch/i386/core/video_subr.c
  31. 317
    0
      src/arch/i386/core/virtaddr.S
  32. 1
    1
      src/arch/i386/drivers/net/undi.c
  33. 73
    105
      src/arch/i386/firmware/pcbios/bios.c
  34. 76
    0
      src/arch/i386/firmware/pcbios/bios_console.c
  35. 0
    85
      src/arch/i386/firmware/pcbios/console.c
  36. 90
    0
      src/arch/i386/firmware/pcbios/gateA20.c
  37. 145
    120
      src/arch/i386/firmware/pcbios/memsizes.c
  38. 10
    0
      src/arch/i386/include/bios.h
  39. 27
    0
      src/arch/i386/include/bochs.h
  40. 1
    1
      src/arch/i386/include/hidemem.h
  41. 12
    7
      src/arch/i386/include/hooks.h
  42. 2
    16
      src/arch/i386/include/io.h
  43. 18
    0
      src/arch/i386/include/kir.h
  44. 184
    0
      src/arch/i386/include/libkir.h
  45. 186
    0
      src/arch/i386/include/librm.h
  46. 34
    0
      src/arch/i386/include/memsizes.h
  47. 2
    2
      src/arch/i386/include/pic8259.h
  48. 0
    1
      src/arch/i386/include/pxe_callbacks.h
  49. 1
    1
      src/arch/i386/include/pxe_types.h
  50. 109
    109
      src/arch/i386/include/realmode.h
  51. 93
    0
      src/arch/i386/include/registers.h
  52. 0
    41
      src/arch/i386/include/segoff.h
  53. 85
    0
      src/arch/i386/include/virtaddr.h
  54. 29
    0
      src/arch/i386/kir-Makefile
  55. 44
    18
      src/arch/i386/prefix/dskprefix.S
  56. 13
    0
      src/arch/i386/prefix/int19exit.c
  57. 121
    77
      src/arch/i386/prefix/unnrv2b.S
  58. 263
    0
      src/arch/i386/scripts/i386.lds
  59. 243
    0
      src/arch/i386/transitions/libkir.S
  60. 0
    0
      src/arch/i386/transitions/libpm.S
  61. 691
    0
      src/arch/i386/transitions/librm.S
  62. 87
    0
      src/arch/i386/transitions/librm_mgmt.c
  63. 4
    1
      src/arch/ia64/core/ia64_timer.c
  64. 1
    0
      src/bin/.cvsignore
  65. 30
    28
      src/core/btext.c
  66. 49
    0
      src/core/config.c
  67. 102
    0
      src/core/console.c
  68. 12
    1
      src/core/heap.c
  69. 44
    0
      src/core/init.c
  70. 13
    124
      src/core/main.c
  71. 1
    142
      src/core/misc.c
  72. 20
    1
      src/core/osloader.c
  73. 10
    6
      src/core/pc_kbd.c
  74. 8
    12
      src/core/pcmcia.c
  75. 0
    6
      src/core/pxe_export.c
  76. 3
    2
      src/core/relocate.c
  77. 35
    41
      src/core/serial.c
  78. 2
    1
      src/drivers/disk/ide_disk.c
  79. 2
    0
      src/drivers/net/3c509.c
  80. 1
    0
      src/drivers/net/3c515.c
  81. 1
    0
      src/drivers/net/cs89x0.c
  82. 1
    0
      src/drivers/net/depca.c
  83. 1
    0
      src/drivers/net/eepro.c
  84. 19
    19
      src/drivers/net/ns83820.c
  85. 3
    1
      src/drivers/net/ns8390.c
  86. 3
    1
      src/drivers/net/prism2_pci.c
  87. 1
    0
      src/drivers/net/sk_g16.c
  88. 1
    0
      src/drivers/net/smc9000.c
  89. 0
    376
      src/genrules.pl
  90. 1
    15
      src/include/btext.h
  91. 41
    0
      src/include/compiler.h
  92. 28
    0
      src/include/console.h
  93. 1
    63
      src/include/etherboot.h
  94. 58
    0
      src/include/init.h
  95. 6
    0
      src/include/main.h
  96. 0
    1
      src/include/osdep.h
  97. 13
    0
      src/include/stddef.h
  98. 0
    1
      src/include/timer.h
  99. 63
    0
      src/util/parserom.pl
  100. 0
    0
      src/util/zfilelen.pl

+ 3
- 2
src/.cvsignore View File

@@ -1,2 +1,3 @@
1
-bin
2
-gcccheck
1
+.toolcheck
2
+TAGS*
3
+bin*

+ 131
- 24
src/Config View File

@@ -424,27 +424,134 @@ CFLAGS+=	-DPXE_IMAGE -DPXE_EXPORT
424 424
 # but this is here for archs that don't support relocation
425 425
 # CFLAGS+=	-DNORELOCATE
426 426
 
427
-# you should normally not need to change these
428
-HOST_CC=	gcc
429
-CPP=		gcc -E -Wp,-Wall
430
-RM=		rm -f
431
-TOUCH=		touch
432
-PERL=		/usr/bin/perl
433
-CC=		gcc
434
-AS=		as
435
-LD=		ld
436
-SIZE=		size
437
-AR=		ar
438
-RANLIB=		ranlib
439
-OBJCOPY=	objcopy
440
-
441
-CFLAGS+=	-Os -ffreestanding
442
-CFLAGS+=	-Wall -W -Wno-format
443
-CFLAGS+=	$(EXTRA_CFLAGS)
444
-ASFLAGS+=	$(EXTRA_ASFLAGS)
445
-LDFLAGS+=	$(EXTRA_LDFLAGS)
446
-# For debugging
447
-# LDFLAGS+=	-Map $@.map
448
-
449
-# Location to place generated binaries, and files
450
-BIN=bin
427
+
428
+
429
+
430
+# Garbage from Makefile.main temporarily placed here until a home can
431
+# be found for it.
432
+
433
+# NS8390 options:
434
+#	-DINCLUDE_NE	- Include NE1000/NE2000 support
435
+#	-DNE_SCAN=list	- Probe for NE base address using list of
436
+#			  comma separated hex addresses
437
+#	-DINCLUDE_3C503 - Include 3c503 support
438
+#	  -DT503_SHMEM	- Use 3c503 shared memory mode (off by default)
439
+#	-DINCLUDE_WD	- Include Western Digital/SMC support
440
+#	-DWD_DEFAULT_MEM- Default memory location for WD/SMC cards
441
+#	-DWD_790_PIO    - Read/write to WD/SMC 790 cards in PIO mode (default
442
+#			  is to use shared memory) Try this if you get "Bogus
443
+#			  packet, ignoring" messages, common on ISA/PCI hybrid
444
+#			  systems.
445
+#	-DCOMPEX_RL2000_FIX
446
+#
447
+#	If you have a Compex RL2000 PCI 32-bit (11F6:1401),
448
+#	and the bootrom hangs in "Probing...[NE*000/PCI]",
449
+#	try enabling this fix... it worked for me :).
450
+#	In the first packet write somehow it somehow doesn't
451
+#	get back the expected data so it is stuck in a loop.
452
+#	I didn't bother to investigate what or why because it works
453
+#	when I interrupt the loop if it takes more then COMPEX_RL2000_TRIES.
454
+#	The code will notify if it does a abort.
455
+#	SomniOne - somnione@gmx.net
456
+#
457
+# 3C509 option:
458
+#	-DINCLUDE_3C509	- Include 3c509 support
459
+#
460
+# 3C90X options:
461
+#	-DINCLUDE_3C90X	- Include 3c90x support
462
+#
463
+#	Warning Warning Warning
464
+#	If you use any of the XCVR options below, please do not complain about
465
+#	the behaviour with Linux drivers to the kernel developers. You are
466
+#	on your own if you do this. Please read 3c90x.txt to understand
467
+#	what they do. If you don't understand them, ask for help on the
468
+#	Etherboot mailing list. And please document what you did to the NIC
469
+#	on the NIC so that people after you won't get nasty surprises.
470
+#
471
+#	-DCFG_3C90X_PRESERVE_XCVR - Reset the transceiver type to the value it
472
+#			  had initially just before the loaded code is started.
473
+#	-DCFG_3C90X_XCVR - Hardcode the tranceiver type Etherboot uses.
474
+#	-DCFG_3C90X_BOOTROM_FIX - If you have a 3c905B with buggy ROM
475
+#			  interface, setting this option might "fix" it.  Use
476
+#			  with caution and read the docs in 3c90x.txt!
477
+#
478
+#	See the documentation file 3c90x.txt for more details.
479
+#
480
+# CS89X0 (optional) options:
481
+#	-DINCLUDE_CS89X0- Include CS89x0 support
482
+#	-DCS_SCAN=list	- Probe for CS89x0 base address using list of
483
+#			  comma separated hex addresses; increasing the
484
+#			  address by one (0x300 -> 0x301) will force a
485
+#			  more aggressive probing algorithm. This might
486
+#			  be neccessary after a soft-reset of the NIC.
487
+#
488
+# LANCE options:
489
+#	-DINCLUDE_NE2100- Include NE2100 support
490
+#	-DINCLUDE_NI6510- Include NI6510 support
491
+#
492
+# SK_G16 options:
493
+#	-DINCLUDE_SK_G16- Include SK_G16 support
494
+#
495
+# I82586 options:
496
+#	-DINCLUDE_3C507	- Include 3c507 support
497
+#	-DINCLUDE_NI5210- Include NI5210 support
498
+#	-DINCLUDE_EXOS205-Include EXOS205 support
499
+#
500
+# SMC9000 options:
501
+#       -DINCLUDE_SMC9000   - Include SMC9000 driver
502
+#       -DSMC9000_SCAN=list - List of I/O addresses to probe
503
+#
504
+# TIARA (Fujitsu Etherstar) options:
505
+#	-DINCLUDE_TIARA	- Include Tiara support
506
+#
507
+# NI5010 options:
508
+#	-DINCLUDE_NI5010 - Include NI5010 support
509
+#
510
+# TULIP options:
511
+#	-DINCLUDE_TULIP	- Include Tulip support
512
+#
513
+# RTL8139 options:
514
+#	-DINCLUDE_RTL8139 - Include RTL8139 support
515
+#
516
+# SIS900 options:
517
+#	-DINCLUDE_SIS900 - Include SIS900 support
518
+#
519
+# NATSEMI options:
520
+#	-DINCLUDE_NATSEMI - Include NATSEMI support
521
+#
522
+
523
+CFLAGS_3c503	= -DINCLUDE_3C503 # -DT503_SHMEM
524
+MAKEROM_FLAGS_3c503=	-3
525
+CFLAGS_3c507	= -DINCLUDE_3C507
526
+CFLAGS_3c509	= -DINCLUDE_3C509
527
+CFLAGS_3c529	= -DINCLUDE_3C529
528
+CFLAGS_3c595	= -DINCLUDE_3C595
529
+CFLAGS_3c90x	= -DINCLUDE_3C90X
530
+CFLAGS_cs89x0	= -DINCLUDE_CS89X0
531
+CFLAGS_eepro	= -DINCLUDE_EEPRO
532
+CFLAGS_eepro100	= -DINCLUDE_EEPRO100
533
+CFLAGS_e1000	= -DINCLUDE_E1000
534
+CFLAGS_epic100	= -DINCLUDE_EPIC100
535
+CFLAGS_exos205	= -DINCLUDE_EXOS205
536
+CFLAGS_lance	= -DINCLUDE_LANCE		# Lance/PCI!
537
+CFLAGS_ne2100	= -DINCLUDE_NE2100
538
+CFLAGS_ne	= -DINCLUDE_NE -DNE_SCAN=0x300,0x280,0x320,0x340,0x380
539
+CFLAGS_ns8390	= -DINCLUDE_NS8390	# NE2000/PCI!
540
+CFLAGS_ni5010	= -DINCLUDE_NI5010
541
+CFLAGS_ni5210	= -DINCLUDE_NI5210
542
+CFLAGS_ni6510	= -DINCLUDE_NI6510
543
+CFLAGS_rtl8139	= -DINCLUDE_RTL8139
544
+CFLAGS_sk_g16	= -DINCLUDE_SK_G16
545
+CFLAGS_sis900   = -DINCLUDE_SIS900
546
+CFLAGS_natsemi  = -DINCLUDE_NATSEMI
547
+CFLAGS_smc9000  = -DINCLUDE_SMC9000
548
+CFLAGS_sundance	= -DINCLUDE_SUNDANCE
549
+CFLAGS_tlan	= -DINCLUDE_TLAN
550
+CFLAGS_tiara	= -DINCLUDE_TIARA
551
+CFLAGS_depca	= -DINCLUDE_DEPCA	
552
+# CFLAGS_depca	+= -DDEPCA_MODEL=DEPCA -DDEPCA_RAM_BASE=0xd0000
553
+CFLAGS_tulip	= -DINCLUDE_TULIP
554
+CFLAGS_otulip	= -DINCLUDE_OTULIP
555
+CFLAGS_via_rhine = -DINCLUDE_VIA_RHINE
556
+CFLAGS_wd	= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xCC000
557
+CFLAGS_w89c840	= -DINCLUDE_W89C840

+ 0
- 133
src/Families View File

@@ -1,133 +0,0 @@
1
-# This is the config file for creating Makefile rules for Etherboot ROMs
2
-#
3
-# To make a ROM for a supported NIC locate the appropriate family
4
-# and add a line of the form
5
-#
6
-# ROM		PCI-IDs		Comment
7
-#
8
-# ROM is the desired output name for both .rom and .lzrom images.
9
-# PCI IDs are the PCI vendor and device IDs of the PCI NIC
10
-# For ISA NICs put -
11
-#
12
-# All PCI ROMs that share a single driver are only built once (because they
13
-# only have different PCI-IDs, but identical code).  ISA ROMS are built for
14
-# each ROM type, because different vendors used a different logic around the
15
-# basic chip.  The most popular example is the NS8390, which some cards use
16
-# in PIO mode, some in DMA mode.  Two chips currently don't fit into this nice
17
-# black-and-white scheme (the Lance and the NS8390).  Their driver deals
18
-# with both PCI and ISA cards.  These drivers will be treated similarly to
19
-# ISA only drivers by genrules.pl and are compiled for each ROM type that is
20
-# ISA, and additionally compiled for the PCI card type.
21
-#
22
-# Then do: make clean, make Roms and make
23
-#
24
-# Please send additions to this file to <kenUNDERSCOREyap AT users PERIOD sourceforge PERIOD net>
25
-
26
-# Start of configuration
27
-
28
-family		drivers/net/skel
29
-
30
-family		arch/ia64/drivers/net/undi_nii
31
-undi_nii	-
32
-
33
-# 3c59x cards (Vortex) and 3c900 cards
34
-# If your 3c900 NIC detects but fails to work, e.g. no link light, with
35
-# the 3c90x driver, try using the 3c595 driver. I have one report that the
36
-# 3c595 driver handles these NICs properly. (The 595 driver uses the
37
-# programmed I/O mode of operation, whereas the 90x driver uses the bus
38
-# mastering mode. These NICs are capable of either mode.) When it comes to
39
-# making a ROM, as usual, you must choose the correct image, the one that
40
-# contains the same PCI IDs as your NIC.
41
-family		drivers/net/3c595
42
-
43
-# 3Com 3c90x cards
44
-family		drivers/net/3c90x
45
-
46
-# Intel Etherexpress Pro/100
47
-family		drivers/net/eepro100
48
-
49
-#Intel Etherexpress Pro/1000
50
-family		drivers/net/e1000
51
-
52
-#Broadcom Tigon 3
53
-family		drivers/net/tg3
54
-
55
-family		drivers/net/pcnet32
56
-
57
-# National Semiconductor ns83820 (Gigabit) family
58
-family		drivers/net/ns83820
59
-
60
-family		drivers/net/tulip
61
-
62
-family		drivers/net/davicom
63
-
64
-family		drivers/net/rtl8139
65
-
66
-family		drivers/net/r8169
67
-
68
-family		drivers/net/via-rhine
69
-
70
-family		drivers/net/w89c840
71
-
72
-family		drivers/net/sis900
73
-
74
-family		drivers/net/natsemi
75
-
76
-family		drivers/net/prism2_plx
77
-
78
-family		drivers/net/prism2_pci
79
-# Various Prism2.5 (PCI) devices that manifest themselves as Harris Semiconductor devices
80
-# (with the actual vendor appearing as the vendor of the first subsystem)
81
-hwp01170	0x1260,0x3873	ActionTec HWP01170
82
-dwl520		0x1260,0x3873	DLink DWL-520
83
-
84
-family		drivers/net/ns8390
85
-wd		-		WD8003/8013, SMC8216/8416, SMC 83c790 (EtherEZ)
86
-ne		-		NE1000/2000 and clones
87
-3c503		-		3Com503, Etherlink II[/16]
88
-
89
-family		drivers/net/epic100
90
-
91
-family		drivers/net/3c509
92
-3c509		-		3c509, ISA/EISA
93
-3c529		-		3c529 == MCA 3c509
94
-
95
-family		drivers/net/3c515
96
-3c515		-		3c515, Fast EtherLink ISA
97
-
98
-family		drivers/net/eepro
99
-eepro		-		Intel Etherexpress Pro/10
100
-
101
-family		drivers/net/cs89x0
102
-cs89x0		-		Crystal Semiconductor CS89x0
103
-
104
-family		drivers/net/depca
105
-depca		-		Digital DE100 and DE200
106
-
107
-family          drivers/net/forcedeth
108
-
109
-family		drivers/net/sk_g16
110
-sk_g16		-		Schneider and Koch G16
111
-
112
-family		drivers/net/smc9000
113
-smc9000		-		SMC9000
114
-
115
-family		drivers/net/sundance
116
-
117
-family		drivers/net/tlan
118
-
119
-family		drivers/disk/ide_disk
120
-ide_disk	0x0000,0x0000	Generic IDE disk support
121
-
122
-family		drivers/disk/pc_floppy
123
-
124
-family		arch/i386/drivers/net/undi
125
-undi		0x0000,0x0000	UNDI driver support
126
-
127
-family		drivers/net/pnic
128
-
129
-family		arch/armnommu/drivers/net/p2001_eth
130
-
131
-family		drivers/net/mtd80x
132
-
133
-family		drivers/net/dmfe

+ 141
- 11
src/Makefile View File

@@ -1,15 +1,145 @@
1
-# Override ARCH here or on the command line
2
-# ARCH=i386
3
-# Additionally you can supply extra compilation arguments, e.g. for x86_64
4
-# EXTRA_CFLAGS=-m32
5
-# EXTRA_ASFLAGS=--32
6
-# EXTRA_LDFLAGS=-m elf_i386
1
+# Initialise variables that get added to throughout the various Makefiles
2
+#
3
+MAKEDEPS	:= Makefile .toolcheck
4
+SRCDIRS		:=
5
+SRCS		:=
6
+NON_AUTO_SRCS	:=
7
+DRIVERS		:=
8
+ROMS		:=
9
+MEDIA		:=
10
+NON_AUTO_MEDIA	:=
11
+
12
+# Grab the central Config file.
13
+#
14
+MAKEDEPS	+= Config
15
+include Config
16
+
17
+# If no architecture is specified in Config or on the command-line,
18
+# use that of the build machine.
19
+#
7 20
 ifndef ARCH
8
-ARCH:=$(shell uname -m | sed -e s,i[3456789]86,i386,)
21
+ARCH		:= $(shell uname -m | sed -e s,i[3456789]86,i386,)
9 22
 endif
10
-MAKEDEPS:=
11
-SUFFIXES:=
12 23
 
13
-include Config
24
+# Drag in architecture-specific Config
25
+#
26
+MAKEDEPS	+= arch/$(ARCH)/Config
14 27
 include arch/$(ARCH)/Config
15
-include Makefile.main
28
+
29
+# If invoked with no build target, print out a helpfully suggestive
30
+# message.
31
+#
32
+noargs : blib
33
+	@echo '===================================================='
34
+	@echo 'No target specified. To specify a target, do: '
35
+	@echo
36
+	@echo '    $(MAKE) bin/<rom-name>.<output-format> '
37
+	@echo
38
+	@echo 'where <output-format> is one of [z]{$(MEDIA) }'
39
+	@echo
40
+	@echo 'or: '
41
+	@echo
42
+	@echo '    $(MAKE) all<output-format>s'
43
+	@echo
44
+	@echo 'to generate all possible images of format <output-format>'
45
+	@echo
46
+	@echo 'For example, '
47
+	@echo
48
+	@echo '    make allzroms '
49
+	@echo
50
+	@echo 'will generate all possible .zrom (rom burnable) images, and'
51
+	@echo
52
+	@echo '    make allzdsks'
53
+	@echo
54
+	@echo 'will generate all possible .zdsk (bootable floppy) images, or'
55
+	@echo
56
+	@echo '===================================================='
57
+	@exit 1
58
+
59
+# Locations of utilities
60
+#
61
+HOST_CC		?= gcc
62
+CPP		?= gcc -E -Wp,-Wall
63
+RM		?= rm -f
64
+TOUCH		?= touch
65
+MKDIR		?= mkdir
66
+PERL		?= /usr/bin/perl
67
+CC		?= $(CROSS_COMPILE)gcc
68
+AS		?= $(CROSS_COMPILE)as
69
+LD		?= $(CROSS_COMPILE)ld
70
+SIZE		?= $(CROSS_COMPILE)size
71
+AR		?= $(CROSS_COMPILE)ar
72
+RANLIB		?= $(CROSS_COMPILE)ranlib
73
+OBJCOPY		?= $(CROSS_COMPILE)objcopy
74
+PARSEROM	?= $(PERL) ./util/parserom.pl
75
+MAKEROM		?= $(PERL) ./util/makerom.pl
76
+NRV2B		?= ./util/nrv2b
77
+
78
+# Location to place generated files
79
+#
80
+BIN		?= bin
81
+
82
+# Library containing all compiled objects
83
+BLIB	= $(BIN)/blib.a
84
+
85
+# Common flags
86
+#
87
+CFLAGS		+= -I include -I arch/$(ARCH)/include -DARCH=$(ARCH)
88
+CFLAGS		+= -Os -ffreestanding
89
+CFLAGS		+= -Wall -W -Wno-format
90
+CFLAGS		+= $(EXTRA_CFLAGS)
91
+ASFLAGS		+= $(EXTRA_ASFLAGS)
92
+LDFLAGS		+= $(EXTRA_LDFLAGS)
93
+
94
+# CFLAGS for specific object types
95
+#
96
+CFLAGS_c	+= 
97
+CFLAGS_S 	+= -DASSEMBLY
98
+
99
+# CFLAGS for specific object files.  You can define
100
+# e.g. CFLAGS_rtl8139, and have those flags automatically used when
101
+# compiling bin/rtl8139.o.
102
+#
103
+OBJ_CFLAGS	= $(CFLAGS_$(basename $(@F))) \
104
+		  -DOBJECT=$(subst -,_,$(basename $(@F)))
105
+$(BIN)/%.flags :
106
+	@echo $(OBJ_CFLAGS)
107
+
108
+# Rules for specific object types.
109
+#
110
+COMPILE_c	= $(CC) $(CFLAGS) $(CFLAGS_c) $(OBJ_CFLAGS)
111
+RULE_c		= $(COMPILE_c) -c $< -o $@
112
+RULE_c_to_s	= $(COMPILE_c) -S -c $< -o $@ 
113
+RULE_c_to_c	= $(COMPILE_c) -E -c $< > $@
114
+
115
+PREPROCESS_S	= $(CPP) $(CFLAGS) $(CFLAGS_S) $(OBJ_CFLAGS)
116
+ASSEMBLE_S	= $(AS) $(ASFLAGS)
117
+RULE_S		= $(PREPROCESS_S) $< | $(ASSEMBLE_S) -o $@
118
+RULE_S_to_s	= $(PREPROCESS_S) $< > $@
119
+
120
+DEBUG_TARGETS	+= c s
121
+
122
+# SRCDIRS lists all directories containing source files.
123
+#
124
+SRCDIRS		+= core drivers/net drivers/disk
125
+
126
+# NON_AUTO_SRCS lists files that are excluded from the normal
127
+# automatic build system.
128
+#
129
+NON_AUTO_SRCS	+= core/elf_loader.c
130
+
131
+# Rules for finalising files.  TGT_MAKEROM_FLAGS is defined as part of
132
+# the automatic build system and varies by target; it includes the
133
+# "-p 0x1234,0x5678" string to set the PCI IDs.
134
+#
135
+FINALISE_rom = $(MAKEROM) $(MAKEROM_FLAGS) $(TGT_MAKEROM_FLAGS) \
136
+	       -i$(IDENT) $@
137
+
138
+# Drag in architecture-specific Makefile
139
+#
140
+MAKEDEPS	+= arch/$(ARCH)/Makefile
141
+include arch/$(ARCH)/Makefile
142
+
143
+# Drag in the automatic build system and other housekeeping functions
144
+MAKEDEPS	+= Makefile.housekeeping
145
+include Makefile.housekeeping

+ 0
- 18
src/Makefile-armnommu View File

@@ -1,18 +0,0 @@
1
-ARCH:=armnommu
2
-MAKEDEPS:=
3
-
4
-include Config
5
-include arch/$(ARCH)/Config
6
-
7
-CC=		$(CROSS_COMPILE)gcc
8
-AS=		$(CROSS_COMPILE)as
9
-LD=		$(CROSS_COMPILE)ld
10
-SIZE=		$(CROSS_COMPILE)size
11
-AR=		$(CROSS_COMPILE)ar
12
-RANLIB=		$(CROSS_COMPILE)ranlib
13
-OBJCOPY=	$(CROSS_COMPILE)objcopy
14
-
15
-MAKEDEPS+=Makefile-armnommu
16
-BIN=bin
17
-
18
-include Makefile.main

+ 0
- 18
src/Makefile-e1 View File

@@ -1,18 +0,0 @@
1
-ARCH:=e1
2
-MAKEDEPS:=
3
-
4
-include arch/$(ARCH)/Config
5
-include Config
6
-
7
-CC=		e1-coff-gcc
8
-AS=		e1-coff-as
9
-LD=		e1-coff-ld
10
-SIZE=	e1-coff-size
11
-AR=		e1-coff-ar
12
-RANLIB=	e1-coff-ranlib
13
-OBJCOPY=e1-coff-objcopy
14
-
15
-MAKEDEPS+=Makefile-e1
16
-BIN=bin-e1
17
-
18
-include Makefile.main

+ 0
- 18
src/Makefile-i386 View File

@@ -1,18 +0,0 @@
1
-ARCH:=i386
2
-MAKEDEPS:=
3
-
4
-include arch/$(ARCH)/Config
5
-include Config
6
-
7
-CC=		i386-linux-gcc
8
-AS=		i386-linux-as
9
-LD=		i386-linux-ld
10
-SIZE=		i386-linux-size
11
-AR=		i386-linux-ar
12
-RANLIB=		i386-linux-ranlib
13
-OBJCOPY=	i386-linux-objcopy
14
-
15
-MAKEDEPS+=Makefile-i386
16
-BIN=bin-i386
17
-
18
-include Makefile.main

+ 0
- 18
src/Makefile-ia64 View File

@@ -1,18 +0,0 @@
1
-ARCH:=ia64
2
-MAKEDEPS:=
3
-
4
-include arch/$(ARCH)/Config
5
-include Config
6
-
7
-CC=		ia64-linux-gcc
8
-AS=		ia64-linux-as
9
-LD=		ia64-linux-ld
10
-SIZE=		ia64-linux-size
11
-AR=		ia64-linux-ar
12
-RANLIB=		ia64-linux-ranlib
13
-OBJCOPY=	ia64-linux-objcopy
14
-
15
-MAKEDEPS+=Makefile-ia64
16
-BIN=bin-ia64
17
-
18
-include Makefile.main

+ 375
- 0
src/Makefile.housekeeping View File

@@ -0,0 +1,375 @@
1
+# -*- makefile -*- : Force emacs to use Makefile mode
2
+
3
+# This file contains various boring housekeeping functions that would
4
+# otherwise seriously clutter up the main Makefile.
5
+
6
+# Objects to be removed by "make clean"
7
+#
8
+CLEANUP	:= $(BIN)/*.* # *.* to avoid catching the "CVS" directory
9
+
10
+# Version number calculations 
11
+#
12
+VERSION_MAJOR	= 5
13
+VERSION_MINOR	= 3
14
+VERSION_PATCH	= 14
15
+EXTRAVERSION	=	
16
+MM_VERSION	= $(VERSION_MAJOR).$(VERSION_MINOR)
17
+VERSION		= $(MM_VERSION).$(VERSION_PATCH)$(EXTRAVERSION)
18
+CFLAGS		+= -DVERSION_MAJOR=$(VERSION_MAJOR) \
19
+		   -DVERSION_MINOR=$(VERSION_MINOR) \
20
+		   -DVERSION=\"$(VERSION)\"
21
+IDENT		= '$(@F) $(VERSION) (GPL) etherboot.org'
22
+version :
23
+	@echo $(VERSION)
24
+
25
+# Check for tools that can cause failed builds
26
+#
27
+.toolcheck : Makefile Config
28
+	@if $(CC) -v 2>&1 | grep -is 'gcc version 2\.96' > /dev/null; then \
29
+		echo 'gcc 2.96 is unsuitable for compiling Etherboot'; \
30
+		echo 'Use gcc 2.95 or gcc 3.x instead'; \
31
+		exit 1; \
32
+	fi
33
+	@if [ `perl -e 'use bytes; print chr(255)' | wc -c` = 2 ]; then \
34
+		echo 'Your Perl version has a Unicode handling bug'; \
35
+		echo 'Execute this command before compiling Etherboot:'; \
36
+		echo 'export LANG=$${LANG%.UTF-8}'; \
37
+		exit 1; \
38
+	fi
39
+	@$(TOUCH) $@
40
+VERYCLEANUP	+= .toolcheck
41
+
42
+# Check for an old version of gas (binutils 2.9.1)
43
+#
44
+OLDGAS	:= $(shell $(AS) --version | grep -q '2\.9\.1' && echo -DGAS291)
45
+CFLAGS	+= $(OLDGAS)
46
+oldgas :
47
+	@echo $(oldgas)
48
+
49
+# SRCDIRS lists all directories containing source files.
50
+srcdirs :
51
+	@echo $(SRCDIRS)
52
+
53
+# SRCS lists all .c or .S files found in any SRCDIR
54
+#
55
+SRCS	+= $(wildcard $(patsubst %,%/*.c,$(SRCDIRS)))
56
+SRCS	+= $(wildcard $(patsubst %,%/*.S,$(SRCDIRS)))
57
+srcs :
58
+	@echo $(SRCS)
59
+
60
+# AUTO_SRCS lists all files in SRCS that are not mentioned in
61
+# NON_AUTO_SRCS.  Files should be added to NON_AUTO_SRCS if they
62
+# cannot be built using the standard build template.
63
+#
64
+AUTO_SRCS = $(filter-out $(NON_AUTO_SRCS),$(SRCS))
65
+autosrcs :
66
+	@echo $(AUTO_SRCS)
67
+
68
+# We automatically generate rules for any file mentioned in AUTO_SRCS
69
+# using the following set of templates.  It would be cleaner to use
70
+# $(eval ...), but this function exists only in GNU make >= 3.80.
71
+
72
+# src_template : generate Makefile rules for a given source file
73
+#
74
+# $(1) is the full path to the source file (e.g. "drivers/net/rtl8139.c")
75
+# $(2) is the full path to the .d file (e.g. "bin/deps/drivers/net/rtl8139.d")
76
+# $(3) is the source type (e.g. "c")
77
+# $(4) is the source base name (e.g. "rtl8139")
78
+#
79
+define src_template
80
+
81
+	@echo "Generating Makefile rules for $(1)"
82
+	@$(MKDIR) -p $(dir $(2))
83
+	@$(RM) $(2)
84
+	@$(TOUCH) $(2)
85
+	$(foreach OBJ,$(if $(OBJS_$(4)),$(OBJS_$(4)),$(4)), \
86
+		$(call obj_template,$(1),$(2),$(3),$(OBJ)))
87
+	@$(PARSEROM) $(1) >> $(2)
88
+
89
+endef
90
+
91
+# obj_template : generate Makefile rules for a given resultant object
92
+# of a particular source file.  (We can have multiple objects per
93
+# source file via the OBJS_xxx list.)
94
+#
95
+# $(1) is the full path to the source file (e.g. "drivers/net/rtl8139.c")
96
+# $(2) is the full path to the .d file (e.g. "bin/deps/drivers/net/rtl8139.d")
97
+# $(3) is the source type (e.g. "c")
98
+# $(4) is the object name (e.g. "rtl8139")
99
+#
100
+define obj_template
101
+
102
+	@$(CPP) $(CFLAGS) $(CFLAGS_$(3)) $(CFLAGS_$(4)) \
103
+		-M $(1) -MT "$(4)_DEPS" | tr : = >> $(2)
104
+	@echo -e '\n$$(BIN)/$(4).o : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
105
+		 '\n\t$$(RULE_$(3))\n' \
106
+		 '\nBOBJS += $$(BIN)/$(4).o\n' \
107
+		 $(foreach TGT,$(DEBUG_TARGETS), \
108
+		    $(if $(RULE_$(3)_to_$(TGT)), \
109
+		    '\n$$(BIN)/$(4).$(TGT) : $(1) $$(MAKEDEPS) $$($(4)_DEPS)' \
110
+		    '\n\t$$(RULE_$(3)_to_$(TGT))\n' ) ) \
111
+		 '\n$(2) : $$($(4)_DEPS)\n' \
112
+		 '\nTAGS : $$($(4)_DEPS)\n' \
113
+		>> $(2)
114
+
115
+endef
116
+
117
+# Rule to generate the Makefile rules files to be included
118
+#
119
+$(BIN)/deps/%.d : % $(MAKEDEPS) $(PARSEROM)
120
+	$(if $(filter $(AUTO_SRCS),$<),$(call src_template,$<,$@,$(subst .,,$(suffix $<)),$(basename $(notdir $<))),@echo 'ERROR: $< is not an AUTO_SRC' ; exit 1)
121
+
122
+# Calculate and include the list of Makefile rules files
123
+#
124
+AUTO_DEPS	= $(patsubst %,$(BIN)/deps/%.d,$(AUTO_SRCS))
125
+include $(AUTO_DEPS)
126
+autodeps :
127
+	@echo $(AUTO_DEPS)
128
+VERYCLEANUP	+= $(BIN)/deps
129
+
130
+# The following variables are created by the Makefile rules files
131
+#
132
+bobjs :
133
+	@echo $(BOBJS)
134
+drivers :
135
+	@echo $(DRIVERS)
136
+.PHONY : drivers
137
+roms :
138
+	@echo $(ROMS)
139
+
140
+# Generate the NIC file from the parsed source files.  The NIC file is
141
+# only for rom-o-matic.
142
+#
143
+$(BIN)/NIC : $(AUTO_DEPS)
144
+	@echo '# This is an automatically generated file, do not edit' > $@
145
+	@echo '# It does not affect anything in the build, ' \
146
+	     'it is only for rom-o-matic' >> $@
147
+	@echo >> $@
148
+	@perl -ne 'chomp; print "$$1\n" if /\# NIC\t(.*)$$/' $^ >> $@
149
+CLEANUP		+= $(BIN)/NIC
150
+
151
+# Library of all objects
152
+#
153
+$(BLIB) : $(BOBJS)
154
+	$(AR) r $@ $(BOBJS)
155
+	$(RANLIB) $@
156
+blib : $(BLIB)
157
+
158
+# Analyse a target name (e.g. "bin/dfe538--prism2_pci.zrom.tmp") and
159
+# derive the variables:
160
+# 
161
+# TGT_ELEMENTS : the elements of the target (e.g. "dfe538 prism2_pci")
162
+# TGT_PREFIX   : the prefix type (e.g. "zrom")
163
+# TGT_DRIVERS  : the driver for each element (e.g. "rtl8139 prism2_pci")
164
+# TGT_ROM_NAME : the ROM name (e.g. "dfe538")
165
+# TGT_MEDIA    : the media type (e.g. "rom")
166
+#
167
+TGT_ELEMENTS	= $(subst --, ,$(firstword $(subst ., ,$(notdir $@))))
168
+TGT_PREFIX	= $(word 2,$(subst ., ,$(notdir $@)))
169
+TGT_DRIVERS	= $(strip $(foreach TGT_ELEMENT,$(TGT_ELEMENTS), \
170
+		   $(firstword $(DRIVER_$(TGT_ELEMENT)) $(TGT_ELEMENT))))
171
+TGT_ROM_NAME	= $(firstword $(TGT_ELEMENTS))
172
+TGT_MEDIA	= $(subst z,,$(TGT_PREFIX))
173
+
174
+# Look up ROM type and IDs for the current target
175
+# (e.g. "bin/dfe538--prism2_pci.zrom.tmp") and derive the variables:
176
+#
177
+# TGT_ROM_TYPE   : PCI/ISA indicator (e.g. "pci")
178
+# TGT_PCI_VENDOR : the PCI vendor ID (e.g. "0x1186")
179
+# TGT_PCI_DEVICE : the PCI device ID (e.g. "0x1300")
180
+#
181
+TGT_ROM_TYPE	= $(ROM_TYPE_$(TGT_ROM_NAME))
182
+TGT_PCI_VENDOR	= $(PCI_VENDOR_$(TGT_ROM_NAME))
183
+TGT_PCI_DEVICE	= $(PCI_DEVICE_$(TGT_ROM_NAME))
184
+
185
+# Calculate link-time options for the current target
186
+# (e.g. "bin/dfe538--prism2_pci.zrom.tmp") and derive the variables:
187
+#
188
+# TGT_LD_DRIVERS : symbols to require in order to drag in the relevant drivers
189
+#		   (e.g. "obj_rtl8139 obj_prism2_pci")
190
+# TGT_LD_PREFIX  : symbols to require in order to drag in the relevant prefix
191
+#		   (e.g. "obj_zpciprefix")
192
+# TGT_LD_IDS :     symbols to define in order to fill in ID structures in the
193
+#		   ROM header (e.g. "pci_vendor=0x1186 pci_device=0x1300")
194
+#
195
+TGT_LD_DRIVERS	= $(subst -,_,$(patsubst %,obj_%,$(TGT_DRIVERS)))
196
+TGT_LD_PREFIX	= obj_$(subst rom,$(TGT_ROM_TYPE),$(TGT_PREFIX))prefix
197
+TGT_LD_IDS	= $(if $(TGT_PCI_VENDOR),pci_vendor=$(TGT_PCI_VENDOR)) \
198
+		  $(if $(TGT_PCI_DEVICE),pci_device=$(TGT_PCI_DEVICE))
199
+
200
+# Calculate linker flags based on link-time options for the current
201
+# target type (e.g. "bin/dfe538--prism2_pci.zrom.tmp") and derive the
202
+# variables:
203
+#
204
+# TGT_LD_FLAGS : target-specific flags to pass to linker (e.g.
205
+#		 "-u obj_zpciprefix -u obj_rtl8139 -u obj_prism2_pci
206
+#		  --defsym pci_vendor=0x1186 --defsym pci_device=0x1300")
207
+#
208
+TGT_LD_FLAGS	= $(foreach SYM,$(TGT_LD_PREFIX) $(TGT_LD_DRIVERS) obj_config,\
209
+		    -u $(SYM) --defsym check_$(SYM)=$(SYM) ) \
210
+		  $(patsubst %,--defsym %,$(TGT_LD_IDS))
211
+
212
+# Calculate makerom flags for the specific target
213
+# (e.g. "bin/dfe538--prism2_pci.zrom.tmp") and derive the variables:
214
+#
215
+# TGT_MAKEROM_FLAGS : target-specific flags for makerom (e.g.
216
+#		      "-p 0x1186,0x1300")
217
+#
218
+TGT_MAKEROM_FLAGS = $(strip $(MAKEROM_FLAGS_$(TGT_ROM_NAME)) \
219
+       $(if $(TGT_PCI_VENDOR),$(strip -p $(TGT_PCI_VENDOR),$(TGT_PCI_DEVICE))))
220
+
221
+# Print out all derived information for a given target.
222
+#
223
+$(BIN)/%.info :
224
+	@echo 'Elements             : $(TGT_ELEMENTS)'
225
+	@echo 'Prefix               : $(TGT_PREFIX)'
226
+	@echo 'Drivers              : $(TGT_DRIVERS)'
227
+	@echo 'ROM name             : $(TGT_ROM_NAME)'
228
+	@echo 'Media                : $(TGT_MEDIA)'
229
+	@echo
230
+	@echo 'ROM type             : $(TGT_ROM_TYPE)'
231
+	@echo 'PCI vendor           : $(TGT_PCI_VENDOR)'
232
+	@echo 'PCI device           : $(TGT_PCI_DEVICE)'
233
+	@echo
234
+	@echo 'LD driver symbols    : $(TGT_LD_DRIVERS)'
235
+	@echo 'LD prefix symbols    : $(TGT_LD_PREFIX)'
236
+	@echo 'LD ID symbols        : $(TGT_LD_IDS)'
237
+	@echo
238
+	@echo 'LD target flags      : $(TGT_LD_FLAGS)'
239
+	@echo
240
+	@echo 'makerom target flags : $(TGT_MAKEROM_FLAGS)'
241
+
242
+# Build an intermediate object file from the objects required for the
243
+# specified target.
244
+#
245
+$(BIN)/%.tmp : $(BLIB) $(MAKEDEPS) $(LDSCRIPT)
246
+	$(LD) $(LDFLAGS) -T $(LDSCRIPT) $(TGT_LD_FLAGS) $< -o $@ \
247
+		-Map $(BIN)/$*.tmp.map
248
+
249
+# Show a linker map for the specified target
250
+#
251
+$(BIN)/%.map : $(BIN)/%.tmp
252
+	@less $(BIN)/$*.tmp.map
253
+
254
+# Rules for each media format.  These are generated and placed in an
255
+# external Makefile fragment.  We could do this via $(eval ...), but
256
+# that would require make >= 3.80.
257
+# 
258
+# Note that there's an alternative way to generate most .rom images:
259
+# they can be copied from their 'master' ROM image using cp and
260
+# reprocessed with makerom to add the PCI IDs and ident string.  The
261
+# relevant rule would look something like:
262
+#
263
+#   $(BIN)/dfe538%rom : $(BIN)/rtl8139%rom
264
+#	cat $< $@
265
+#	$(FINALISE_rom)
266
+# 
267
+# You can derive the ROM/driver relationships using the variables
268
+# DRIVER_<rom> and/or ROMS_<driver>.
269
+# 
270
+# We don't currently do this, because (a) it would require generating
271
+# yet more Makefile fragments (since you need a rule for each ROM in
272
+# ROMS), and (b) the linker is so fast that it probably wouldn't make
273
+# much difference to the overall build time.
274
+
275
+media :
276
+	@echo $(MEDIA)
277
+
278
+AUTO_MEDIA	= $(filter-out $(NON_AUTO_MEDIA),$(MEDIA))
279
+automedia :
280
+	@echo $(AUTO_MEDIA)
281
+
282
+# media_template : create Makefile rules for specified media
283
+#
284
+# $(1) is the media name (e.g. "rom")
285
+# $(2) is the full path to the .d file (e.g. "bin/deps/rom.media.d")
286
+#
287
+define media_template
288
+
289
+	@echo "Generating Makefile rules for $(1) media"
290
+	@$(MKDIR) -p $(dir $(2))
291
+	@$(RM) $(2)
292
+	@$(TOUCH) $(2)
293
+	@echo -e '$$(BIN)/%$(1) : $$(BIN)/%$(1).tmp' \
294
+		  '\n\t$$(OBJCOPY) -O binary $$< $$@' \
295
+		  '\n\t$$(FINALISE_$(1))' \
296
+		> $(2)
297
+
298
+endef
299
+
300
+# Rule to generate the Makefile rules to be included
301
+#
302
+$(BIN)/deps/%.media.d : $(MAKEDEPS)
303
+	$(if $(filter $(AUTO_MEDIA),$*), \
304
+		$(call media_template,$*,$@), \
305
+		@echo 'ERROR: $* is not an AUTO_MEDIA' ; exit 1)
306
+
307
+# Calculate and include the list of Makefile rules files
308
+#
309
+MEDIA_DEPS		= $(patsubst %,$(BIN)/deps/%.media.d,$(AUTO_MEDIA))
310
+mediadeps :
311
+	@echo $(MEDIA_DEPS)
312
+include $(MEDIA_DEPS)
313
+
314
+# The "allXXXs" targets for each suffix
315
+#
316
+allroms allzroms : all%s : $(foreach ROM,$(ROMS),$(BIN)/$(ROM).%)
317
+all%s : $(foreach DRIVER,$(DRIVERS),$(BIN)/$(DRIVER).%)
318
+
319
+# The compressor utility
320
+#
321
+$(NRV2B) : util/nrv2b.c $(MAKEDEPS)
322
+	$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG \
323
+		       -DBITSIZE=32 -DENDIAN=0 -o $@ $<
324
+CLEANUP	+= $(NRV2B)
325
+
326
+# Auto-incrementing build serial number.  Append "bs" to your list of
327
+# build targets to get a serial number printed at the end of the
328
+# build.  Enable -DBUILD_SERIAL in order to see it when the code runs.
329
+#
330
+BUILDSERIAL_H = include/.buildserial.h
331
+
332
+$(BUILDSERIAL_H) :
333
+	@if [ ! -s $@ ]; then echo '#define BUILD_SERIAL_NUM 0' > $@; fi
334
+	@perl -pi -e 's/(BUILD_SERIAL_NUM)\s+(\d+)/"$${1} ".($${2}+1)/e' $@
335
+
336
+bs : $(BUILDSERIAL_H)
337
+	@perl -n -e '/BUILD_SERIAL_NUM\s+(\d+)/ && ' \
338
+		-e 'print "Build serial number is $$1\n";' $<
339
+
340
+ifeq ($(filter bs,$(MAKECMDGOALS)),bs)
341
+.PHONY : $(BUILDSERIAL_H)
342
+endif
343
+
344
+# Ensure that include/.buildserial.h always exists, to solve the
345
+# problem of bootstrapping a BUILD_SERIAL-enabled build.
346
+#
347
+ifeq ($(wildcard $(BUILDSERIAL_H)),)
348
+$(shell $(TOUCH) $(BUILDSERIAL_H))
349
+endif
350
+
351
+# List of available architectures
352
+#
353
+ARCHS	= $(filter-out CVS,$(patsubst arch/%,%,$(wildcard arch/*)))
354
+archs :
355
+	@echo $(ARCHS)
356
+
357
+OTHER_ARCHS	= $(filter-out $(ARCH),$(ARCHS))
358
+otherarchs :
359
+	@echo $(OTHER_ARCHS)
360
+
361
+# Build the TAGS file for emacs
362
+#
363
+TAGS : TAGS.$(ARCH)
364
+
365
+TAGS.$(ARCH) : 
366
+	ctags -e -R -f $@ $(foreach ARCH,$(OTHER_ARCHS),--exclude=arch/$(ARCH))
367
+CLEANUP	+= TAGS*
368
+
369
+# Clean-up
370
+#
371
+clean :
372
+	$(RM) $(CLEANUP)
373
+
374
+veryclean : clean
375
+	$(RM) -r $(VERYCLEANUP)

+ 0
- 445
src/Makefile.main View File

@@ -1,445 +0,0 @@
1
-#
2
-# Makefile for Etherboot
3
-#
4
-# Most of the time you should edit Config
5
-#
6
-# Common options:
7
-#	VERSION_*=v	- Set the major and minor version numbers
8
-#
9
-# NS8390 options:
10
-#	-DINCLUDE_NE	- Include NE1000/NE2000 support
11
-#	-DNE_SCAN=list	- Probe for NE base address using list of
12
-#			  comma separated hex addresses
13
-#	-DINCLUDE_3C503 - Include 3c503 support
14
-#	  -DT503_SHMEM	- Use 3c503 shared memory mode (off by default)
15
-#	-DINCLUDE_WD	- Include Western Digital/SMC support
16
-#	-DWD_DEFAULT_MEM- Default memory location for WD/SMC cards
17
-#	-DWD_790_PIO    - Read/write to WD/SMC 790 cards in PIO mode (default
18
-#			  is to use shared memory) Try this if you get "Bogus
19
-#			  packet, ignoring" messages, common on ISA/PCI hybrid
20
-#			  systems.
21
-#	-DCOMPEX_RL2000_FIX
22
-#
23
-#	If you have a Compex RL2000 PCI 32-bit (11F6:1401),
24
-#	and the bootrom hangs in "Probing...[NE*000/PCI]",
25
-#	try enabling this fix... it worked for me :).
26
-#	In the first packet write somehow it somehow doesn't
27
-#	get back the expected data so it is stuck in a loop.
28
-#	I didn't bother to investigate what or why because it works
29
-#	when I interrupt the loop if it takes more then COMPEX_RL2000_TRIES.
30
-#	The code will notify if it does a abort.
31
-#	SomniOne - somnione@gmx.net
32
-#
33
-# 3C509 option:
34
-#	-DINCLUDE_3C509	- Include 3c509 support
35
-#
36
-# 3C90X options:
37
-#	-DINCLUDE_3C90X	- Include 3c90x support
38
-#
39
-#	Warning Warning Warning
40
-#	If you use any of the XCVR options below, please do not complain about
41
-#	the behaviour with Linux drivers to the kernel developers. You are
42
-#	on your own if you do this. Please read 3c90x.txt to understand
43
-#	what they do. If you don't understand them, ask for help on the
44
-#	Etherboot mailing list. And please document what you did to the NIC
45
-#	on the NIC so that people after you won't get nasty surprises.
46
-#
47
-#	-DCFG_3C90X_PRESERVE_XCVR - Reset the transceiver type to the value it
48
-#			  had initially just before the loaded code is started.
49
-#	-DCFG_3C90X_XCVR - Hardcode the tranceiver type Etherboot uses.
50
-#	-DCFG_3C90X_BOOTROM_FIX - If you have a 3c905B with buggy ROM
51
-#			  interface, setting this option might "fix" it.  Use
52
-#			  with caution and read the docs in 3c90x.txt!
53
-#
54
-#	See the documentation file 3c90x.txt for more details.
55
-#
56
-# CS89X0 (optional) options:
57
-#	-DINCLUDE_CS89X0- Include CS89x0 support
58
-#	-DCS_SCAN=list	- Probe for CS89x0 base address using list of
59
-#			  comma separated hex addresses; increasing the
60
-#			  address by one (0x300 -> 0x301) will force a
61
-#			  more aggressive probing algorithm. This might
62
-#			  be neccessary after a soft-reset of the NIC.
63
-#
64
-# LANCE options:
65
-#	-DINCLUDE_NE2100- Include NE2100 support
66
-#	-DINCLUDE_NI6510- Include NI6510 support
67
-#
68
-# SK_G16 options:
69
-#	-DINCLUDE_SK_G16- Include SK_G16 support
70
-#
71
-# I82586 options:
72
-#	-DINCLUDE_3C507	- Include 3c507 support
73
-#	-DINCLUDE_NI5210- Include NI5210 support
74
-#	-DINCLUDE_EXOS205-Include EXOS205 support
75
-#
76
-# SMC9000 options:
77
-#       -DINCLUDE_SMC9000   - Include SMC9000 driver
78
-#       -DSMC9000_SCAN=list - List of I/O addresses to probe
79
-#
80
-# TIARA (Fujitsu Etherstar) options:
81
-#	-DINCLUDE_TIARA	- Include Tiara support
82
-#
83
-# NI5010 options:
84
-#	-DINCLUDE_NI5010 - Include NI5010 support
85
-#
86
-# TULIP options:
87
-#	-DINCLUDE_TULIP	- Include Tulip support
88
-#
89
-# RTL8139 options:
90
-#	-DINCLUDE_RTL8139 - Include RTL8139 support
91
-#
92
-# SIS900 options:
93
-#	-DINCLUDE_SIS900 - Include SIS900 support
94
-#
95
-# NATSEMI options:
96
-#	-DINCLUDE_NATSEMI - Include NATSEMI support
97
-#
98
-
99
-SRCS:=
100
-BOBJS:=
101
-
102
-MAKEROM=	$(PERL) ./util/makerom.pl
103
-VERSION_MAJOR=	5
104
-VERSION_MINOR=	3
105
-VERSION_PATCH=	14
106
-EXTRAVERSION=	
107
-VERSION=	$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)$(EXTRAVERSION)
108
-MM_VERSION=	$(VERSION_MAJOR).$(VERSION_MINOR)
109
-CFLAGS+=	-DVERSION_MAJOR=$(VERSION_MAJOR) \
110
-		-DVERSION_MINOR=$(VERSION_MINOR) \
111
-		-DVERSION=\"$(VERSION)\" $(OLDGAS) \
112
-		-I include -I arch/$(ARCH)/include \
113
-		-DARCH=$(ARCH)
114
-FILO=filo
115
-FILO_PROGRAM_NAME = FILO
116
-FILO_PROGRAM_VERSION = 0.4.1
117
-FILO_BUILD_INFO = ($(shell whoami)@$(shell hostname)) $(shell LANG=C date)
118
-
119
-GCCINCDIR = $(shell $(CC) -print-search-dirs | head -n 1 | cut -d' ' -f2)include
120
-CPPFLAGS = -nostdinc -imacros filo/config.h 
121
-#-Ifilo/include -I$(GCCINCDIR) -MD
122
-ASFLAGS_X = -D__ASSEMBLY__
123
-
124
-IDENT=		'$(@F) $(VERSION) (GPL) etherboot.org'
125
-
126
-# Find out if we're using binutils 2.9.1 which uses a different syntax in some
127
-# places (most prominently in the opcode prefix area).
128
-OLDGAS:=	$(shell $(AS) --version | grep -q '2\.9\.1' && echo -DGAS291)
129
-
130
-BUILD_LIBS=	$(BLIB)
131
-BUILD_IMGS=	$(IMGS)
132
-
133
-3C503FLAGS=	-DINCLUDE_3C503 # -DT503_SHMEM
134
-# Note that the suffix to MAKEROM_ is the (mixed case) basename of the ROM file
135
-MAKEROM_3c503=	-3
136
-3C507FLAGS=	-DINCLUDE_3C507
137
-3C509FLAGS=	-DINCLUDE_3C509
138
-3C529FLAGS=	-DINCLUDE_3C529
139
-3C595FLAGS=	-DINCLUDE_3C595
140
-3C90XFLAGS=	-DINCLUDE_3C90X
141
-CS89X0FLAGS=	-DINCLUDE_CS89X0
142
-EEPROFLAGS=	-DINCLUDE_EEPRO
143
-EEPRO100FLAGS=	-DINCLUDE_EEPRO100
144
-E1000FLAGS=	-DINCLUDE_E1000
145
-EPIC100FLAGS=	-DINCLUDE_EPIC100
146
-EXOS205FLAGS=	-DINCLUDE_EXOS205
147
-LANCEFLAGS=	-DINCLUDE_LANCE		# Lance/PCI!
148
-NE2100FLAGS=	-DINCLUDE_NE2100
149
-NEFLAGS=	-DINCLUDE_NE -DNE_SCAN=0x300,0x280,0x320,0x340,0x380
150
-NS8390FLAGS=	-DINCLUDE_NS8390	# NE2000/PCI!
151
-NI5010FLAGS=	-DINCLUDE_NI5010
152
-NI5210FLAGS=	-DINCLUDE_NI5210
153
-NI6510FLAGS=	-DINCLUDE_NI6510
154
-RTL8139FLAGS=	-DINCLUDE_RTL8139
155
-SK_G16FLAGS=	-DINCLUDE_SK_G16
156
-SIS900FLAGS=   	-DINCLUDE_SIS900
157
-NATSEMIFLAGS=  	-DINCLUDE_NATSEMI
158
-SMC9000FLAGS=   -DINCLUDE_SMC9000
159
-SUNDANCEFLAGS=	-DINCLUDE_SUNDANCE
160
-TLANFLAGS=	-DINCLUDE_TLAN
161
-TIARAFLAGS=	-DINCLUDE_TIARA
162
-DEPCAFLAGS=	-DINCLUDE_DEPCA	# -DDEPCA_MODEL=DEPCA -DDEPCA_RAM_BASE=0xd0000
163
-TULIPFLAGS=	-DINCLUDE_TULIP
164
-OTULIPFLAGS=	-DINCLUDE_OTULIP
165
-VIA_RHINEFLAGS=	-DINCLUDE_VIA_RHINE
166
-WDFLAGS=	-DINCLUDE_WD -DWD_DEFAULT_MEM=0xCC000
167
-W89C840FLAGS=	-DINCLUDE_W89C840
168
-
169
-SRCS+=	core/serial.c
170
-
171
-SRCS+=	core/btext.c core/pc_kbd.c
172
-
173
-SRCS+=	core/main.c core/pci.c core/osloader.c core/nfs.c
174
-SRCS+=	core/misc.c core/config.c core/isa_probe.c core/pci_probe.c
175
-SRCS+=	core/relocate.c core/heap.c
176
-SRCS+=	drivers/disk/floppy.c core/nic.c core/disk.c core/timer.c
177
-SRCS+=	core/proto_eth_slow.c
178
-SRCS+=	core/proto_slam.c core/proto_tftm.c core/proto_http.c
179
-SRCS+=	core/isapnp.c
180
-SRCS+=	core/pcmcia.c core/i82365.c
181
-SRCS+=	core/pxe_export.c core/dns_resolver.c
182
-
183
-FILO_SRCS+=	$(FILO)/drivers/ide_x.c  
184
-FILO_SRCS+=	$(FILO)/fs/blockdev.c $(FILO)/fs/eltorito.c $(FILO)/fs/fsys_ext2fs.c $(FILO)/fs/fsys_fat.c $(FILO)/fs/fsys_iso9660.c
185
-FILO_SRCS+=	$(FILO)/fs/fsys_reiserfs.c $(FILO)/fs/vfs.c $(FILO)/fs/fsys_jfs.c $(FILO)/fs/fsys_minix.c $(FILO)/fs/fsys_xfs.c  
186
-FILO_SRCS+=	$(FILO)/main/elfload.c $(FILO)/main/elfnote.c $(FILO)/main/filo_x.c $(FILO)/main/lib.c $(FILO)/main/linuxbios_x.c 
187
-FILO_SRCS+=	$(FILO)/main/pci_x.c $(FILO)/main/malloc_x.c $(FILO)/main/printf_x.c $(FILO)/main/console_x.c 
188
-FILO_SRCS+=	$(FILO)/$(ARCH)/context.c $(FILO)/$(ARCH)/linux_load.c $(FILO)/$(ARCH)/segment.c $(FILO)/$(ARCH)/sys_info.c 
189
-FILO_SRCS+=	$(FILO)/$(ARCH)/switch.S $(FILO)/usb/debug_x.c $(FILO)/usb/scsi_cmds.c $(FILO)/usb/uhci.c $(FILO)/usb/usb.c 
190
-FILO_SRCS+=	$(FILO)/usb/ohci.c $(FILO)/usb/usb_scsi_low.c  $(FILO)/usb/usb_x.c
191
-
192
-
193
-BOBJS+=		$(BIN)/main.o $(BIN)/osloader.o $(BIN)/nfs.o $(BIN)/misc.o
194
-BOBJS+=		$(BIN)/proto_slam.o $(BIN)/proto_tftm.o $(BIN)/proto_http.o
195
-BOBJS+=		$(BIN)/floppy.o
196
-BOBJS+=		$(BIN)/serial.o $(BIN)/timer.o  $(BIN)/relocate.o $(BIN)/heap.o
197
-BOBJS+=		$(BIN)/btext.o $(BIN)/pc_kbd.o
198
-BOBJS+=		$(BIN)/nic.o $(BIN)/disk.o
199
-BOBJS+=		$(BIN)/isapnp.o
200
-BOBJS+=		$(BIN)/pci.o $(BIN)/isa_probe.o $(BIN)/pci_probe.o
201
-BOBJS+=		$(BIN)/vsprintf.o $(BIN)/string.o
202
-BOBJS+=		$(BIN)/pcmcia.o $(BIN)/i82365.o
203
-BOBJS+=		$(BIN)/pxe_export.o $(BIN)/dns_resolver.o
204
-
205
-FILO_OBJS+=		$(BIN)/ide_x.o $(BIN)/pci_x.o
206
-FILO_OBJS+=		$(BIN)/blockdev.o $(BIN)/eltorito.o $(BIN)/fsys_ext2fs.o $(BIN)/fsys_fat.o $(BIN)/fsys_iso9660.o $(BIN)/fsys_reiserfs.o $(BIN)/vfs.o
207
-FILO_OBJS+=		$(BIN)/fsys_jfs.o $(BIN)/fsys_minix.o $(BIN)/fsys_xfs.o  
208
-FILO_OBJS+=		$(BIN)/elfload.o  $(BIN)/elfnote.o  $(BIN)/filo_x.o $(BIN)/lib.o $(BIN)/linuxbios_x.o $(BIN)/malloc_x.o $(BIN)/printf_x.o $(BIN)/console_x.o   
209
-FILO_OBJS+=		$(BIN)/context.o  $(BIN)/linux_load.o  $(BIN)/segment.o  $(BIN)/sys_info.o $(BIN)/switch.o
210
-FILO_OBJS+=		$(BIN)/debug_x.o  $(BIN)/scsi_cmds.o $(BIN)/uhci.o $(BIN)/usb.o $(BIN)/ohci.o $(BIN)/usb_scsi_low.o $(BIN)/usb_x.o
211
-
212
-BLIB=		$(BIN)/bootlib.a 
213
-FILOLIB=	$(BIN)/filolib.a
214
-LIBS=		$(BLIB)
215
-ifdef	INCLUDE_FILO
216
-LIBS+=		$(FILOLIB)
217
-endif
218
-UTILS+=		$(BIN)/nrv2b
219
-STDDEPS=	$(START) $(UTILS)
220
-# MAKEDEPS is the one target that is depended by all ROMs, so we check gcc here
221
-# If you are confident that gcc 2.96 works for you, you can remove the lines
222
-# that check gcc in the toolcheck rule
223
-MAKEDEPS+=	Makefile Makefile.main Config genrules.pl Families
224
-MAKEDEPS+=	$(BIN)/toolcheck
225
-MAKEDEPS+=	arch/$(ARCH)/Makefile arch/$(ARCH)/Config
226
-
227
-# Start of targets
228
-
229
-.PHONY:	noargs
230
-noargs:	$(BIN)/toolcheck
231
-	@echo '===================================================='
232
-	@echo 'No target specified. To specify a target, do: '
233
-	@echo
234
-	@echo '    $(MAKE) bin/<rom-name>.<output-format> '
235
-	@echo
236
-	@echo 'where <output-format> is one of {zdsk, zrom, iso, liso, zlilo, zpxe, elf, com}'
237
-	@echo
238
-	@echo 'or: '
239
-	@echo
240
-	@echo '    $(MAKE) all<output-format>s'
241
-	@echo
242
-	@echo 'to generate all possible images of format <output-format>'
243
-	@echo
244
-	@echo 'For example, '
245
-	@echo
246
-	@echo '    make allzroms '
247
-	@echo
248
-	@echo 'will generate all possible .zrom (rom burnable) images, and'
249
-	@echo
250
-	@echo '    make allzdsks'
251
-	@echo
252
-	@echo 'will generate all possible .zdsk (bootable floppy) images, or'
253
-	@echo
254
-	@echo '===================================================='
255
-	@exit 1
256
-
257
-$(BIN)/toolcheck:	Makefile Config
258
-	@if $(CC) -v 2>&1 | grep -is 'gcc version 2\.96' > /dev/null; \
259
-	then \
260
-		echo 'gcc 2.96 is unsuitable for compiling Etherboot'; \
261
-		echo 'Use gcc 2.95 or gcc 3.x instead'; \
262
-		exit 1; \
263
-	else \
264
-		touch $(BIN)/toolcheck; \
265
-	fi; \
266
-	if [ `perl -e 'use bytes; print chr(255)' | wc -c` = 2 ]; \
267
-	then \
268
-		echo 'Your Perl version has a Unicode handling bug'; \
269
-		echo 'To workaround, execute this before compiling Etherboot:'; \
270
-		echo 'export LANG=$${LANG%.UTF-8}'; \
271
-		exit 1; \
272
-	fi
273
-
274
-include		arch/$(ARCH)/Makefile
275
-
276
-# Common files
277
-
278
-$(BLIB):	$(BOBJS)
279
-	$(AR) r $@ $(BOBJS)
280
-	$(RANLIB) $@
281
-
282
-$(FILOLIB):	$(FILO_OBJS)
283
-	$(AR) r $@ $(FILO_OBJS)
284
-	$(RANLIB) $@
285
-
286
-# LinuxBIOS support code
287
-$(BIN)/linuxbios.o:	firmware/linuxbios/linuxbios.c include/etherboot.h include/dev.h firmware/linuxbios/linuxbios_tables.h
288
-
289
-# Do not add driver specific dependencies here unless it's something the
290
-# genrules.pl script *can't* deal with, i.e. if it is not C code.
291
-
292
-$(FILO)/config.h: $(FILO)/Config
293
-	/bin/echo -e '/* GENERATED FILE, DO NOT EDIT */\n' >$@
294
-	sed -e 's/#.*//' -e '/=/!d' -e 's/\([^[:space:]]*\)[[:space:]]*=[[:space:]]*\(.*\).*/#define \1 \2/' -e 's/^#define \([^ ]*\) 0$$/#undef \1/' $^ >>$@
295
-
296
-filo_version: $(FILO)/main/version.h
297
-
298
-$(FILO)/main/version.h: FORCE
299
-	echo '#define PROGRAM_NAME "$(FILO_PROGRAM_NAME)"' > $@
300
-	echo '#define PROGRAM_VERSION "$(FILO_PROGRAM_VERSION) $(FILO_BUILD_INFO)"' >> $@
301
-
302
-FORCE:
303
-
304
-
305
-# Roms file
306
-# Builds almost silently because this rule is triggered for just about
307
-# every modification to sources.
308
-
309
-$(BIN)/Roms $(BIN)/NIC:	genrules.pl Families $(SRCS)
310
-	@mkdir -p $(@D)
311
-	@echo Scanning for ROMs and dependencies...
312
-	@$(PERL) ./genrules.pl Families $(BIN)/NIC $(ARCH) $(SRCS) > $(BIN)/Roms
313
-
314
-# Pattern Rules
315
-
316
-# general rules for compiling/assembling source files
317
-$(BIN)/%.o:	core/%.c $(MAKEDEPS)
318
-	$(CC) $(CFLAGS) -o $@ -c $<
319
-
320
-$(BIN)/%.s:	core/%.c $(MAKEDEPS)
321
-	$(CC) $(CFLAGS) -S -o $@ -c $<
322
-
323
-$(BIN)/%.o:	drivers/disk/%.c $(MAKEDEPS)
324
-	$(CC) $(CFLAGS) -o $@ -c $<
325
-
326
-$(BIN)/%.o:	drivers/net/%.c $(MAKEDEPS)
327
-	$(CC) $(CFLAGS) -o $@ -c $<
328
-
329
-$(BIN)/%.o:	firmware/linuxbios/%.c $(MAKEDEPS)
330
-	$(CC) $(CFLAGS) -o $@ -c $<
331
-
332
-$(BIN)/%.o:     $(FILO)/drivers/%.c $(MAKEDEPS) $(FILO)/config.h
333
-	$(CC) $(CFLAGS) -imacros $(FILO)/config.h -o $@ -c $<
334
-
335
-$(BIN)/%.o:     $(FILO)/fs/%.c $(MAKEDEPS) $(FILO)/config.h
336
-	$(CC) $(CFLAGS) -imacros $(FILO)/config.h -o $@ -c $<
337
-
338
-$(BIN)/%.o:     $(FILO)/$(ARCH)/%.c $(MAKEDEPS) $(FILO)/config.h
339
-	$(CC) $(CFLAGS) -imacros $(FILO)/config.h -o $@ -c $<
340
-
341
-$(BIN)/%.o:     $(FILO)/$(ARCH)/%.S $(MAKEDEPS) $(FILO)/config.h
342
-	$(CC) $(ASFLAGS_X) $(CPPFLAGS) -c $< -o $@
343
-
344
-$(BIN)/%.o:     $(FILO)/main/%.c $(MAKEDEPS) $(FILO)/config.h filo_version
345
-	$(CC) $(CFLAGS) -imacros $(FILO)/config.h -o $@ -c $<
346
-
347
-$(BIN)/%.o:     $(FILO)/usb/%.c $(MAKEDEPS) $(FILO)/config.h
348
-	$(CC) $(CFLAGS) -imacros $(FILO)/config.h -o $@ -c $<
349
-
350
-# Rule for the super etherboot image.
351
-$(BIN)/etherboot.o: $(DOBJS)
352
-	$(LD) $(LDFLAGS) -r $(DOBJS) -o $@
353
-
354
-$(BIN)/etherboot-pci.o: $(PCIOBJS)
355
-	$(LD) $(LDFLAGS) -r $(PCIOBJS) -o $@
356
-
357
-# General rules for generating runtime (rt) files
358
-$(BIN)/%.rt.o:  $(BIN)/%.o $(START) $(BIN)/config.o $(LIBS) $(STDDEPS) $(MAKEDEPS)
359
-	$(LD) $(LDFLAGS) -r $(START) $(BIN)/config.o $< $(LIBS) -o $@
360
-
361
-#   Rule for $(BIN)/%.FORMAT.rt is architecture and target-format specific
362
-
363
-$(BIN)/%.rt.bin: $(BIN)/%.rt $(MAKEDEPS)
364
-	$(OBJCOPY) -O binary -R .prefix $< $@
365
-
366
-$(BIN)/%.rt1.bin: $(BIN)/%.rt $(MAKEDEPS)
367
-	$(OBJCOPY) -O binary -j .text.nocompress $< $@
368
-
369
-$(BIN)/%.rt2.bin: $(BIN)/%.rt $(MAKEDEPS)
370
-	$(OBJCOPY) -O binary -R .prefix -R .text.nocompress $< $@
371
-
372
-# Rules for generating prefix binary files
373
-
374
-#   Rule for $(BIN)/%.FORMAT.prf is architecture and target-format specific
375
-$(BIN)/%.prf.bin: $(BIN)/%.prf $(MAKEDEPS)
376
-	$(OBJCOPY) -j .prefix -O binary $< $@
377
-
378
-# general rule for .z (compressed binary code), may be overridden
379
-$(BIN)/%.zbin: $(BIN)/%.bin $(BIN)/nrv2b $(MAKEDEPS)
380
-	$(BIN)/nrv2b e $< $@
381
-
382
-# Housekeeping
383
-
384
-clean:
385
-	$(RM) $(BIN)/*
386
-	$(RM) $(FILO)/config.h $(FILO)/main/version.h
387
-
388
-../index.html:	../index.xhtml
389
-	(cd ..; m4 -P -DHOSTSITE=SOURCEFORGE index.xhtml > index.html)
390
-
391
-../index-berlios.html:	../index.xhtml
392
-	(cd ..; m4 -P -DHOSTSITE=BERLIOS index.xhtml > index-berlios.html)
393
-
394
-tarball: ../index.html ../index-berlios.html
395
-	(echo -n $(VERSION) ''; date -u +'%Y-%m-%d') > ../VERSION
396
-	(cd ../..; tar cf /tmp/etherboot-$(VERSION).tar --exclude CVS --exclude doc etherboot-$(VERSION))
397
-	bzip2 -9 < /tmp/etherboot-$(VERSION).tar > /tmp/etherboot-$(VERSION).tar.bz2
398
-	gzip -9 < /tmp/etherboot-$(VERSION).tar > /tmp/etherboot-$(VERSION).tar.gz
399
-
400
-# Auto-incrementing build serial number.  Is auto-incremented for each
401
-# make run that specifies a final image file (e.g. bin/undi.zpxe) as a
402
-# target, or a target of the form "all*".  Enable via -DBUILD_SERIAL
403
-# in Config.
404
-
405
-ifneq ($(findstring -DBUILD_SERIAL,$(CFLAGS)),)
406
-
407
-# If no make goals are specified, it means "make all"
408
-REALGOALS = $(if $(MAKECMDGOALS),$(MAKECMDGOALS),all)
409
-
410
-# Filter to see if there are any targets to trigger an auto-increment
411
-BUILDGOALS = $(filter all,$(REALGOALS)) $(filter all%,$(REALGOALS)) \
412
-	     $(foreach SUFFIX,$(SUFFIXES),$(filter %.$(SUFFIX),$(REALGOALS)))
413
-
414
-ifneq ($(strip $(BUILDGOALS)),)
415
-# This is an auto-incrementing build.  Forcibly rebuild .buildserial.h
416
-# and mark config.o as depending on it to force its rebuilding.
417
-bin/config.o : include/.buildserial.h
418
-.PHONY : include/.buildserial.h
419
-endif # BUILDGOALS
420
-
421
-include/.buildserial.h :
422
-	@if [ ! -f $@ ]; then 	echo '#define BUILD_SERIAL_NUM 0' > $@; fi
423
-	@perl -pi -e 's/(BUILD_SERIAL_NUM)\s+(\d+)/"$${1} ".($${2}+1)/e' $@
424
-
425
-buildserial : include/.buildserial.h
426
-	@perl -n -e '/BUILD_SERIAL_NUM\s+(\d+)/ && ' \
427
-		-e 'print "Build serial number is $$1\n";' $<
428
-
429
-else # -DBUILD_SERIAL
430
-
431
-buildserial : 
432
-	@echo Build serial number is disabled. Enable -DBUILD_SERIAL in Config.
433
-
434
-endif # -DBUILD_SERIAL
435
-
436
-bs : buildserial
437
-
438
-version:
439
-	@echo $(VERSION)
440
-
441
-romlimit:
442
-	@echo $(ROMLIMIT)
443
-
444
-sources:
445
-	@echo $(SRCS)

+ 4
- 2
src/arch/armnommu/core/arm_timer.c View File

@@ -9,7 +9,7 @@
9 9
 #include "timer.h"
10 10
 #include "latch.h"
11 11
 #include "hardware.h"
12
-
12
+#include "init.h"
13 13
 
14 14
 /* get timer returns the contents of the timer */
15 15
 static unsigned long get_timer(void)
@@ -29,7 +29,7 @@ static unsigned long configure_timer(void)
29 29
 
30 30
 static unsigned long clocks_per_tick = 1;
31 31
 
32
-void setup_timers(void)
32
+static void setup_timers(void)
33 33
 {
34 34
 	if (!clocks_per_tick) {
35 35
 		clocks_per_tick = configure_timer();
@@ -75,3 +75,5 @@ int timer2_running(void)
75 75
 {
76 76
 	return __timer_running();
77 77
 }
78
+
79
+INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );

+ 4
- 1
src/arch/e1/core/e1_timer.c View File

@@ -7,6 +7,7 @@
7 7
 #include "etherboot.h"
8 8
 #include "timer.h"
9 9
 #include "e132_xs_board.h"
10
+#include "init.h"
10 11
 
11 12
 /* get timer returns the contents of the timer */
12 13
 static inline unsigned long get_timer(void)
@@ -46,7 +47,7 @@ static unsigned long configure_timer(void)
46 47
 
47 48
 static unsigned long clocks_per_tick;
48 49
 
49
-void setup_timers(void)
50
+static void setup_timers(void)
50 51
 {
51 52
 	if (!clocks_per_tick) {
52 53
 		clocks_per_tick = configure_timer();
@@ -92,3 +93,5 @@ int timer2_running(void)
92 93
 {
93 94
 	return __timer_running();
94 95
 }
96
+
97
+INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );

+ 5
- 0
src/arch/i386/Config View File

@@ -129,3 +129,8 @@ endif
129 129
 
130 130
 # An alternate location for isolinux.bin can be set here
131 131
 # ISOLINUX_BIN=/path/to/isolinux.bin
132
+
133
+# These seem to have some relevance to compiling on x86_64
134
+# EXTRA_CFLAGS=-m32
135
+# EXTRA_ASFLAGS=--32
136
+# EXTRA_LDFLAGS=-m elf_i386

+ 124
- 369
src/arch/i386/Makefile View File

@@ -1,375 +1,130 @@
1
-ARCH_FORMAT=	elf32-i386
2
-
3
-# For debugging, don't delete intermediates
4
-#.SECONDARY:
5
-
6
-LDSCRIPT=	arch/i386/core/etherboot.lds
7
-PLDSCRIPT=	arch/i386/core/etherboot.prefix.lds
8
-
9
-LCONFIG+=	-Ui386
10
-
11
-ROMLIMIT=	524288
12
-CHECKSIZE=	{ read d1; read d1 d2 d3 size d4; [ $$size -gt $(ROMLIMIT) ] &&\
13
-	{ $(RM) $@; echo "ERROR: code size exceeds limit!"; exit 1; }; exit 0; }
14
-
15
-START=	$(BIN)/start32.o $(BIN)/linuxbios.o \
16
-	$(BIN)/bios.o $(BIN)/console.o $(BIN)/memsizes.o $(BIN)/basemem.o \
17
-	$(BIN)/hidemem.o $(BIN)/e820mangler.o \
18
-	$(BIN)/realmode.o $(BIN)/realmode_asm.o \
19
-	$(BIN)/callbacks.o $(BIN)/pxe_callbacks.o
20
-
21
-SRCS+=	arch/i386/prefix/floppyprefix.S
22
-SRCS+=	arch/i386/prefix/unnrv2b.S
23
-SRCS+=	arch/i386/firmware/pcbios/bios.c
24
-SRCS+=	arch/i386/firmware/pcbios/console.c
25
-SRCS+=	arch/i386/firmware/pcbios/memsizes.c
26
-SRCS+=	arch/i386/firmware/pcbios/basemem.c
27
-SRCS+=	arch/i386/firmware/pcbios/hidemem.c
28
-SRCS+=	arch/i386/firmware/pcbios/e820mangler.S
29
-SRCS+=	arch/i386/prefix/liloprefix.S
30
-SRCS+=	arch/i386/prefix/elfprefix.S
31
-SRCS+=	arch/i386/prefix/lmelf_prefix.S
32
-SRCS+=	arch/i386/prefix/elf_dprefix.S
33
-SRCS+=	arch/i386/prefix/lmelf_dprefix.S
34
-SRCS+=	arch/i386/prefix/comprefix.S
35
-SRCS+=	arch/i386/prefix/exeprefix.S
36
-SRCS+=	arch/i386/prefix/pxeprefix.S
37
-SRCS+=	arch/i386/prefix/romprefix.S
38
-
39
-SRCS+=	arch/i386/core/init.S
40
-SRCS+=	arch/i386/core/start32.S
41
-SRCS+=	arch/i386/core/pci_io.c
42
-SRCS+=	arch/i386/core/i386_timer.c
43
-SRCS+=	arch/i386/core/elf.c
44
-SRCS+=	arch/i386/core/cpu.c
45
-SRCS+=	arch/i386/core/video_subr.c
46
-SRCS+=	arch/i386/core/pic8259.c
47
-SRCS+=	arch/i386/core/hooks.c
48
-SRCS+=	arch/i386/core/callbacks.c
49
-SRCS+=	arch/i386/core/realmode.c
50
-SRCS+=	arch/i386/core/realmode_asm.S
51
-SRCS+=	arch/i386/core/pxe_callbacks.c
52
-
53
-# ROM loaders: ISA and PCI versions
54
-ISAPREFIX=	$(BIN)/isaprefix.o
55
-ISAENTRY=	$(BIN)/isaprefix.entry.o
56
-ISAEXIT=	$(BIN)/isaprefix.exit.o
57
-PCIPREFIX=	$(BIN)/pciprefix.o
58
-PCIENTRY=	$(BIN)/pciprefix.entry.o
59
-PCIEXIT=	$(BIN)/pciprefix.exit.o
60
-# Variables xxx_ROMTYPE are defined by genrules.pl.  ROMENTRY and
61
-# ROMEXIT will evaluate to give the correct objects to use.
62
-TARGETBASE=$(patsubst $(BIN)/%,%,$(firstword $(subst ., ,$@)))
63
-ROMCARD=$(firstword $(subst --, ,$(TARGETBASE)))
64
-ROMTYPE=$(firstword $(ROMTYPE_$(ROMCARD)) ISA)
65
-romENTRY=$($(ROMTYPE)ENTRY)
66
-romEXIT=$($(ROMTYPE)EXIT)
67
-
68
-# Target type for generic prf rules
69
-TARGETTYPE=$(patsubst .%,%, $(suffix $(basename $@)))
70
-TARGETENTRY=$($(TARGETTYPE)ENTRY)
71
-TARGETEXIT=$($(TARGETTYPE)EXIT)
72
-
73
-# Other real-mode entry loaders
74
-dskPREFIX=	$(BIN)/floppyprefix.o
75
-dskENTRY=	$(BIN)/floppyprefix.entry.o
76
-dskEXIT=	$(BIN)/floppyprefix.exit.o
77
-comPREFIX=	$(BIN)/comprefix.o
78
-comENTRY=	$(BIN)/comprefix.entry.o
79
-comEXIT=	$(BIN)/comprefix.exit.o
80
-exePREFIX=	$(BIN)/exeprefix.o
81
-exeENTRY=	$(BIN)/exeprefix.entry.o
82
-exeEXIT=	$(BIN)/exeprefix.exit.o
83
-liloPREFIX=	$(BIN)/liloprefix.o
84
-liloENTRY=	$(BIN)/liloprefix.entry.o
85
-liloEXIT=	$(BIN)/liloprefix.exit.o
86
-bImagePREFIX=	$(BIN)/bImageprefix.o
87
-bImageENTRY=	$(BIN)/bImageprefix.entry.o
88
-bImageEXIT=	$(BIN)/bImageprefix.exit.o
89
-pxePREFIX=	$(BIN)/pxeprefix.o
90
-pxeENTRY=	$(BIN)/pxeprefix.entry.o
91
-pxeEXIT=	$(BIN)/pxeprefix.exit.o
92
-rawPREFIX=	$(BIN)/nullprefix.o
93
-rawENTRY=	$(BIN)/nullprefix.entry.o
94
-rawEXIT=	$(BIN)/nullprefix.exit.o
95
-
96
-# Protected mode entry loaders
97
-elfPREFIX=	$(BIN)/elfprefix.o
98
-elfENTRY=	$(BIN)/elfprefix.entry.o
99
-elfEXIT=	$(BIN)/elfprefix.exit.o
100
-lmelfPREFIX=	$(BIN)/lmelf_prefix.o
101
-lmelfENTRY=	$(BIN)/lmelf_prefix.entry.o
102
-lmelfEXIT=	$(BIN)/lmelf_prefix.exit.o
103
-elfdPREFIX=	$(BIN)/elf_dprefix.o
104
-elfdENTRY=	$(BIN)/elf_dprefix.entry.o
105
-elfdEXIT=	$(BIN)/elf_dprefix.exit.o
106
-lmelfdPREFIX=	$(BIN)/lmelf_dprefix.o
107
-lmelfdENTRY=	$(BIN)/lmelf_dprefix.entry.o
108
-lmelfdEXIT=	$(BIN)/lmelf_dprefix.exit.o
109
-
110
-include		$(BIN)/Roms
111
-
112
-all:		$(ROMS)
113
-allroms:	$(ROMS)
114
-allzroms:	$(ROMS)
115
-alldsks:	$(EB_DSKS)
116
-allzdsks:	$(EB_ZDSKS)
117
-alllilos:	$(EB_LILOS)
118
-allzlilos:	$(EB_ZLILOS)
119
-allbImages:	$(EB_BIMAGES)
120
-allbzImages:	$(EB_BZIMAGES)
121
-allpxes:	$(EB_PXES)
122
-allzpxes:	$(EB_ZPXES)
123
-allelfs:	$(EB_ELFS)
124
-allzelfs:	$(EB_ZELFS)
125
-alllmelfs:	$(EB_LMELFS)
126
-allzlmelfs:	$(EB_ZLMELFS)
127
-allelfds:	$(EB_ELFDS)
128
-allzelfds:	$(EB_ZELFDS)
129
-alllmelfds:	$(EB_LMELFDS)
130
-allzlmelfds:	$(EB_ZLMELFDS)
131
-allcoms:	$(EB_COMS)
132
-allexes:	$(EB_EXES)
133
-allisos:	$(EB_ISOS)
134
-alllisos:	$(EB_LISOS)
135
-
136
-BOBJS+=		$(BIN)/pci_io.o $(BIN)/i386_timer.o
137
-BOBJS+=		$(BIN)/elf.o $(BIN)/cpu.o $(BIN)/video_subr.o
138
-BOBJS+=		$(BIN)/pic8259.o $(BIN)/hooks.o
139
-
140
-# ROM loaders
141
-
142
-$(ISAPREFIX):	arch/i386/prefix/romprefix.S $(MAKEDEPS)
143
-	$(CPP) $(CFLAGS) $(LCONFIG) -Ui386 -D ASSEMBLY $< \
144
-		| $(AS) $(ASFLAGS) -o $@ 
145
-
146
-$(PCIPREFIX):	arch/i386/prefix/romprefix.S $(MAKEDEPS)
147
-	$(CPP) -DPCI_PNP_HEADER $(CFLAGS) $(LCONFIG) -Ui386 -D ASSEMBLY $< \
148
-		| $(AS) $(ASFLAGS) -o $@ 
149
-
150
-# Prefix splitters
151
-$(BIN)/%prefix.entry.o: $(BIN)/%prefix.o $(MAKEDEPS)
152
-	$(OBJCOPY) -R .text16 $< $@
153
-
154
-$(BIN)/%prefix.exit.o: $(BIN)/%prefix.o $(MAKEDEPS)
155
-	$(OBJCOPY) -R .prefix $< $@
156
-
157
-# Generic prefix objects
158
-PREFIXOBJS = $(BIN)/init.o
159
-ZPREFIXOBJS = $(BIN)/init.o $(BIN)/unnrv2b.o
160
-
161
-# Utilities
162
-$(BIN)/nrv2b:	util/nrv2b.c
163
-	$(HOST_CC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -DNDEBUG -DBITSIZE=32 -DENDIAN=0 -o $@ $<
164
-
165
-ZFILELEN = perl util/zfilelen.pl
166
-
167
-# Pattern Rules
168
-
169
-# General for compiling/assembly source files
170
-
171
-$(BIN)/%.o:	arch/i386/core/%.c $(MAKEDEPS)
172
-	$(CC) $(CFLAGS) -o $@ -c $<
173
-
174
-$(BIN)/%.o:	arch/i386/core/%.S $(MAKEDEPS)
175
-	$(CPP) $(CFLAGS) -Ui386 -D ASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
176
-
177
-$(BIN)/%.o:	arch/i386/firmware/pcbios/%.c $(MAKEDEPS)
178
-	$(CC) $(CFLAGS) -o $@ -c $<
179
-
180
-$(BIN)/%.o:	arch/i386/firmware/pcbios/%.S $(MAKEDEPS)
181
-	$(CPP) $(CFLAGS) -Ui386 -DASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
182
-
183
-$(BIN)/%.o:	arch/i386/prefix/%.S $(MAKEDEPS)
184
-	$(CPP) $(CFLAGS) -Ui386 -DASSEMBLY $< | $(AS) $(ASFLAGS) -o $@
185
-
186
-$(BIN)/%16.o:	arch/i386/prefix/%.S $(MAKEDEPS)
187
-	$(CPP) $(CFLAGS) -Ui386 -DASSEMBLY -DCODE16 $< | $(AS) $(ASFLAGS) -o $@
188
-
189
-# general rule for 16bit .o, may be overridden
190
-$(BIN)/%.o:	$(BIN)/%.s
191
-	$(AS) $(ASFLAGS) -o $@ $<
192
-
193
-# general rule for .bin (plain binary loader code), may be overridden
194
-$(BIN)/%.bin:	$(BIN)/%.o
195
-	$(OBJCOPY) -O binary $< $@
196
-
197
-# general rule for .z (compressed binary code), may be overridden
198
-# rule for .z is in top level Makefile
199
-# Give the directory name, e.g. use $(BIN)/rtl8139.com as the target.
200
-
201
-$(BIN)/%.zo:	$(BIN)/%.zbin arch/i386/core/prefixzdata.lds $(MAKEDEPS)
202
-	$(LD) -T arch/i386/core/prefixzdata.lds -b binary $< -o $@
203
-
204
-$(BIN)/%.uo:	$(BIN)/%.bin arch/i386/core/prefixudata.lds $(MAKEDEPS)
205
-	$(LD) -T arch/i386/core/prefixudata.lds -b binary $< -o $@
206
-
207
-# Intermediate prf rules
208
-
209
-%.prf:  %.rt $(PREFIXOBJS) %.rt1.uo %.rt2.uo $(MAKEDEPS)
210
-	$(MAKE) $(TARGETENTRY)
211
-	$(LD) $(LDFLAGS) -T $(PLDSCRIPT) $(TARGETENTRY) -R $(subst $(MAKEDEPS),,$^)  -o $@ 
212
-
213
-%.zprf:  %.rt $(ZPREFIXOBJS) %.rt1.uo %.rt2.zo $(MAKEDEPS)
214
-	$(MAKE) $(TARGETENTRY)
215
-	$(LD) $(LDFLAGS) -T $(PLDSCRIPT) $(TARGETENTRY) -R $(subst $(MAKEDEPS),,$^)  -o $@ 
216
-
217
-# general rules for normal/compressed ROM images, may be overridden
218
-SUFFIXES +=	rom zrom
219
-
220
-$(BIN)/%.rom.rt: $(BIN)/%.rt.o  $(ISAENTRY) $(PCIENTRY) $(ISAEXIT) $(PCIEXIT) $(LDSCRIPT) $(MAKEDEPS)
221
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $(romEXIT) $<
222
-	@$(SIZE) $@ | $(CHECKSIZE)
223
-
224
-$(BIN)/%.rom: $(BIN)/%.rom.prf
225
-	$(OBJCOPY) -O binary $< $@
226
-	$(MAKEROM) $(MAKEROM_FLAGS) $(MAKEROM_$(ROMCARD)) $(MAKEROM_ID_$(ROMCARD)) -i$(IDENT) $@
227
-
228
-$(BIN)/%.zrom: $(BIN)/%.rom.zprf
229
-	$(OBJCOPY) -O binary $< $@
230
-	$(MAKEROM) $(MAKEROM_FLAGS) $(MAKEROM_$(ROMCARD)) $(MAKEROM_ID_$(ROMCARD)) -i$(IDENT) $@
231
-
232
-# general rules for ELF images
233
-SUFFIXES +=	elf zelf
234
-$(BIN)/%.elf.rt:  $(BIN)/%.rt.o $(elfENTRY) $(elfEXIT) $(LDSCRIPT) $(MAKEDEPS)
235
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $(elfEXIT)  $< 
236
-
237
-$(BIN)/%.elf: $(BIN)/%.elf.prf
238
-	$(OBJCOPY) -O binary $< $@
239
-
240
-$(BIN)/%.zelf: $(BIN)/%.elf.zprf 
241
-	$(OBJCOPY) -O binary $< $@
242
-
243
-# general rules for Long Mode ELF images
244
-SUFFIXES +=	lmelf zlmelf
245
-$(BIN)/%.lmelf.rt: $(BIN)/%.rt.o $(lmelfENTRY) $(lmelfEXIT) $(LDSCRIPT) $(MAKEDEPS)
246
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $(lmelfEXIT) $<
247
-
248
-$(BIN)/%.lmelf: $(BIN)/%.lmelf.prf
249
-	$(OBJCOPY) -O binary $< $@
250
-
251
-$(BIN)/%.zlmelf: $(BIN)/%.lmelf.zprf
252
-	$(OBJCOPY) -O binary $< $@
253
-
254
-# general rules for ELF dynamic images
255
-SUFFIXES +=	elfd zelfd
256
-$(BIN)/%.elfd.rt: $(BIN)/%.rt.o $(elfdENTRY) $(elfdEXIT) $(LDSCRIPT) $(MAKEDEPS)
257
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $(elfdEXIT) $<
258
-
259
-$(BIN)/%.elfd: $(BIN)/%.elfd.prf
260
-	$(OBJCOPY) -O binary $< $@
261
-
262
-$(BIN)/%.zelfd: $(BIN)/%.elfd.zprf
263
-	$(OBJCOPY) -O binary $< $@
264
-
265
-# general rules for Long Mode ELF dynamic images
266
-SUFFIXES +=	lmelfd zlmelfd
267
-$(BIN)/%.lmelfd.rt: $(BIN)/%.rt.o $(lmelfdENTRY) $(lmelfdEXIT) $(LDSCRIPT) $(MAKEDEPS)
268
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $(lmelfdEXIT) $<
269
-
270
-$(BIN)/%.lmelfd: $(BIN)/%.lmelfd.prf
271
-	$(OBJCOPY) -O binary $< $@
272
-
273
-$(BIN)/%.zlmelfd: $(BIN)/%.lmelfd.zprf
274
-	$(OBJCOPY) -O binary $< $@
275
-
276
-# rules to generate a DOS loadable .com executable
277
-SUFFIXES +=	com
278
-$(BIN)/%.com.rt: $(BIN)/%.rt.o $(comENTRY) $(comEXIT) $(LDSCRIPT) $(MAKEDEPS)
279
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $< $(comEXIT)
280
-
281
-$(BIN)/%.com: $(BIN)/%.com.zprf
282
-	$(OBJCOPY) -O binary $< $@
283
-
284
-# rules to generate a DOS loadable .exe executable
285
-SUFFIXES +=	exe
286
-$(BIN)/%.exe.rt: $(BIN)/%.rt.o $(exeENTRY) $(exeEXIT) $(LDSCRIPT) $(MAKEDEPS)
287
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $< $(exeEXIT)
288
-	@$(SIZE) $@ | $(CHECKSIZE)
289
-
290
-$(BIN)/%.exe: $(BIN)/%.exe.prf
291
-	$(OBJCOPY) -O binary $< $@
292
-
293
-# rules to make a LILO loadable image
294
-SUFFIXES +=	lilo zlilo
295
-
296
-$(BIN)/%.lilo.rt: $(BIN)/%.rt.o $(liloENTRY) $(liloEXIT) $(LDSCRIPT) $(MAKEDEPS)
297
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $< $(liloEXIT)
298
-	@$(SIZE) $@ | $(CHECKSIZE)
299
-
300
-$(BIN)/%.lilo: $(BIN)/%.lilo.prf
301
-	$(OBJCOPY) -O binary $< $@
302
-
303
-$(BIN)/%.zlilo: $(BIN)/%.lilo.zprf
304
-	$(OBJCOPY) -O binary $< $@
305
-
306
-# rules to make big linux boot protocol image
307
-SUFFIXES +=	bImage bzImage
308
-
309
-$(BIN)/%.bImage.rt: $(BIN)/%.rt.o $(bImageENTRY) $(bImageEXIT) $(LDSCRIPT) $(MAKEDEPS)
310
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $< $(bImageEXIT)
311
-
312
-$(BIN)/%.bImage: $(BIN)/%.bImage.prf
313
-	$(OBJCOPY) -O binary $< $@
314
-
315
-$(BIN)/%.bzImage: $(BIN)/%.bImage.zprf
316
-	$(OBJCOPY) -O binary $< $@
317
-
318
-
319
-# rules to generate a PXE loadable image
320
-SUFFIXES +=	pxe zpxe
321
-
322
-$(BIN)/%.pxe.rt: $(BIN)/%.rt.o $(pxeENTRY) $(pxeEXIT) $(LDSCRIPT) $(MAKEDEPS)
323
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $< $(pxeEXIT)
324
-	@$(SIZE) $@ | $(CHECKSIZE)
325
-
326
-$(BIN)/%.pxe: $(BIN)/%.pxe.prf
327
-	$(OBJCOPY) -O binary $< $@
328
-
329
-$(BIN)/%.zpxe: $(BIN)/%.pxe.zprf
330
-	$(OBJCOPY) -O binary $< $@
331
-
332
-# rules to generate the .dsk/.zdsk floppy images
333
-SUFFIXES +=	dsk zdsk
334
-
335
-$(BIN)/%.dsk.rt: $(BIN)/%.rt.o $(dskENTRY) $(dskEXIT) $(LDSCRIPT) $(MAKEDEPS)
336
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $< $(dskEXIT)
337
-	@$(SIZE) $@ | $(CHECKSIZE)
338
-
339
-$(BIN)/%.dsk: $(BIN)/%.dsk.prf
340
-	$(OBJCOPY) -O binary $< $@
341
-
342
-$(BIN)/%.zdsk: $(BIN)/%.dsk.zprf
343
-	$(OBJCOPY) -O binary $< $@
344
-
345
-# rules to write the .dsk/.zdsk image onto a blank floppy
346
-SUFFIXES +=	fd0 zfd0
347
-%.fd0:	%.dsk
348
-	dd if=$< bs=512 conv=sync of=/dev/fd0
349
-	sync
350
-
351
-%.zfd0:	%.zdsk
1
+# i386-specific directories containing source files
2
+#
3
+SRCDIRS		+= arch/i386/core arch/i386/transitions arch/i386/prefix
4
+SRCDIRS		+= arch/i386/firmware/pcbios arch/i386/firmware/linuxbios
5
+SRCDIRS		+= arch/i386/drivers/net
6
+
7
+# The various xxx_loader.c files are #included into core/loader.c and
8
+# should not be compiled directly.
9
+#
10
+NON_AUTO_SRCS	+= arch/i386/core/aout_loader.c
11
+NON_AUTO_SRCS	+= arch/i386/core/freebsd_loader.c
12
+NON_AUTO_SRCS	+= arch/i386/core/multiboot_loader.c
13
+NON_AUTO_SRCS	+= arch/i386/core/tagged_loader.c
14
+NON_AUTO_SRCS	+= arch/i386/core/wince_loader.c
15
+
16
+# setup.S and unnrv2b.S are both used to generate 16-bit as well as
17
+# 32-bit objects.
18
+#
19
+OBJS_setup		= setup setup16
20
+CFLAGS_setup16		= -DCODE16
21
+OBJS_unnrv2b		= unnrv2b unnrv2b16
22
+CFLAGS_unnrv2b16	= -DCODE16
23
+
24
+# hooks.c is used to generate hooks.o and hooks_rm.o
25
+#
26
+OBJS_hooks		= hooks hooks_rm
27
+CFLAGS_hooks_rm		= -DREALMODE
28
+
29
+# We need to undefine the default macro "i386" when compiling .S
30
+# files, otherwise ".arch i386" translates to ".arch 1"...
31
+#
32
+CFLAGS_S		+= -Ui386
33
+
34
+# The i386 linker script
35
+#
36
+LDSCRIPT		= arch/i386/scripts/i386.lds
37
+
38
+# Media types.
39
+# 
40
+# It's ugly that we have to define these repetitive combinations by
41
+# hand.  Unforunately, $(eval ...) is available only in make >= 3.80,
42
+# and using an external Makefile fragment doesn't work because
43
+# OBJS_xxx need to be defined *before* the external Makefile fragments
44
+# for the source files are generated...
45
+
46
+CFLAGS_ZPREFIX		= -DCOMPRESS
47
+
48
+MEDIA			+= rom
49
+OBJS_romprefix		= isaprefix zisaprefix pciprefix zpciprefix
50
+CFLAGS_isaprefix	=
51
+CFLAGS_zisaprefix	= $(CFLAGS_ZPREFIX)
52
+CFLAGS_pciprefix	= -DPCI_PNP_HEADER
53
+CFLAGS_zpciprefix	= $(CFLAGS_pciprefix) $(CFLAGS_ZPREFIX)
54
+
55
+MEDIA			+= pxe
56
+OBJS_pxeprefix		= pxeprefix zpxeprefix
57
+CFLAGS_zpxeprefix	= $(CFLAGS_ZPREFIX)
58
+
59
+MEDIA			+= elf
60
+OBJS_elfprefix		= elfprefix zelfprefix
61
+CFLAGS_zelfprefix	= $(CFLAGS_ZPREFIX)
62
+
63
+MEDIA			+= elfd
64
+OBJS_elfdprefix		= elfdprefix zelfdprefix
65
+CFLAGS_zelfdprefix	= $(CFLAGS_ZPREFIX)
66
+
67
+MEDIA			+= lmelf
68
+OBJS_lmelfprefix	= lmelfprefix zlmelfprefix
69
+CFLAGS_zlmelfprefix	= $(CFLAGS_ZPREFIX)
70
+
71
+MEDIA			+= lmelfd
72
+OBJS_lmelfdprefix	= lmelfdprefix zlmelfdprefix
73
+CFLAGS_zlmelfdprefix	= $(CFLAGS_ZPREFIX)
74
+
75
+MEDIA			+= lilo
76
+OBJS_liloprefix		= liloprefix zliloprefix
77
+CFLAGS_zliloprefix	= $(CFLAGS_ZPREFIX)
78
+
79
+MEDIA			+= bImage
80
+OBJS_bImageprefix	= bImageprefix zbImageprefix
81
+CFLAGS_zbImageprefix	= $(CFLAGS_ZPREFIX)
82
+
83
+MEDIA			+= dsk
84
+OBJS_dskprefix		= dskprefix zdskprefix
85
+CFLAGS_zdskprefix	= $(CFLAGS_ZPREFIX)
86
+
87
+MEDIA			+= raw
88
+OBJS_rawprefix		= rawprefix zrawprefix
89
+CFLAGS_zrawprefix	= $(CFLAGS_ZPREFIX)
90
+
91
+# These media cannot handle compressed payloads
92
+
93
+MEDIA			+= com
94
+
95
+MEDIA			+= exe
96
+
97
+# Some suffixes (e.g. %.zfd0) are generated directly from other
98
+# finished files (e.g. %.zdsk), rather than having their own prefix.
99
+
100
+# rule to write disk images to /dev/fd0
101
+NON_AUTO_MEDIA		+= fd0
102
+%fd0 : %dsk
352 103
 	dd if=$< bs=512 conv=sync of=/dev/fd0
353 104
 	sync
354 105
 
355
-# rules to create raw executable images
356
-SUFFIXES +=	raw zraw
357
-$(BIN)/%.raw.rt: $(BIN)/%.rt.o $(rawENTRY) $(rawEXIT) $(LDSCRIPT) $(MAKEDEPS)
358
-	$(LD) $(LDFLAGS) -T $(LDSCRIPT) -o $@ $< $(rawEXIT)
359
-
360
-$(BIN)/%.raw: $(BIN)/%.raw.prf
361
-	$(OBJCOPY) -O binary $< $@
362
-
363
-$(BIN)/%.zraw: $(BIN)/%.raw.zprf
364
-	$(OBJCOPY) -O binary $< $@
365
-
366 106
 # rule to make a non-emulation ISO boot image
367
-SUFFIXES +=	iso
368
-%.iso:	util/geniso %.zlilo
369
-	ISOLINUX_BIN=${ISOLINUX_BIN} bash util/geniso $*.iso $*.zlilo
107
+NON_AUTO_MEDIA		+= iso
108
+%iso:	%lilo util/geniso
109
+	ISOLINUX_BIN=$(ISOLINUX_BIN) bash util/geniso $@ $<
370 110
 
371 111
 # rule to make a floppy emulation ISO boot image
372
-SUFFIXES +=	liso
373
-%.liso:	util/genliso %.zlilo
374
-	bash util/genliso $*.liso $*.zlilo
375
-
112
+NON_AUTO_MEDIA		+= liso
113
+%liso:	%lilo util/genliso
114
+	bash util/genliso $@ $<
115
+
116
+# Add NON_AUTO_MEDIA to the media list, so that they show up in the
117
+# output of "make"
118
+#
119
+MEDIA		+= $(NON_AUTO_MEDIA)
120
+
121
+# Shortcut to allow typing just
122
+#   make bin-kir/%
123
+# rather than
124
+#   make -f arch/i386/kir-Makefile bin-kir/%
125
+# for building a KEEP_IT_REAL flavour.
126
+#
127
+$(BIN)-kir/% : kir-target
128
+	$(MAKE) -f arch/i386/kir-Makefile $(MAKECMDGOALS)
129
+
130
+.PHONY : kir-target

+ 197
- 0
src/arch/i386/README.i386 View File

@@ -0,0 +1,197 @@
1
+Etherboot/NILO i386 initialisation path and external call interface
2
+===================================================================
3
+
4
+1. Background
5
+
6
+GCC compiles 32-bit code.  It is capable of producing
7
+position-independent code, but the resulting binary is about 25%
8
+bigger than the corresponding fixed-position code.  Since one main use
9
+of Etherboot is as firmware to be burned into an EPROM, code size must
10
+be kept as small as possible.
11
+
12
+This means that we want to compile fixed-position code with GCC, and
13
+link it to have a predetermined start address.  The problem then is
14
+that we must know the address that the code will be loaded to when it
15
+runs.  There are several ways to solve this:
16
+
17
+1. Pick an address, link the code with this start address, then make
18
+   sure that the code gets loaded at that location.  This is
19
+   problematic, because we may pick an address that we later end up
20
+   wanting to use to load the operating system that we're booting.
21
+
22
+2. Pick an address, link the code with this start address, then set up
23
+   virtual addressing so that the virtual addresses match the
24
+   link-time addresses regardless of the real physical address that
25
+   the code is loaded to.  This enables us to relocate Etherboot to
26
+   the top of high memory, where it will be out of the way of any
27
+   loading operating system.
28
+
29
+3. Link the code with a text start address of zero and a data start
30
+   address also of zero.  Use 16-bit real mode and the
31
+   quasi-position-independence it gives you via segment addressing.
32
+   Doing this requires that we generate 16-bit code, rather than
33
+   32-bit code, and restricts us to a maximum of 64kB in each segment.
34
+
35
+There are other possible approaches (e.g. including a relocation table
36
+and code that performs standard dynamic relocation), but the three
37
+options listed above are probably the best available.
38
+
39
+Etherboot can be invoked in a variety of ways (ROM, floppy, as a PXE
40
+NBP, etc).  Several of these ways involve control being passed to
41
+Etherboot with the CPU in 16-bit real mode.  Some will involve the CPU
42
+being in 32-bit protected mode, and there's an outside chance that
43
+some may involve the CPU being in 16-bit protected mode.  We will
44
+almost certainly have to effect a CPU mode change in order to reach
45
+the mode we want to be in to execute the C code.
46
+
47
+Additionally, Etherboot may wish to call external routines, such as
48
+BIOS interrupts, which must be called in 16-bit real mode.  When
49
+providing a PXE API, Etherboot must provide a mechanism for external
50
+code to call it from 16-bit real mode.
51
+
52
+Not all i386 builds of Etherboot will want to make real-mode calls.
53
+For example, when built for LinuxBIOS rather than the standard PCBIOS,
54
+no real-mode calls are necessary.
55
+
56
+For the ultimate in PXE compatibility, we may want to build Etherboot
57
+to run permanently in real mode.
58
+
59
+There is a wide variety of potential combinations of mode switches
60
+that we may wish to implement.  There are additional complications,
61
+such as the inability to access a high-memory stack when running in
62
+real mode.
63
+
64
+2. Transition libraries
65
+
66
+To handle all these various combinations of mode switches, we have
67
+several "transition" libraries in Etherboot.  We also have the concept
68
+of an "internal" and an "external" environment.  The internal
69
+environment is the environment within which we can execute C code.
70
+The external environment is the environment of whatever external code
71
+we're trying to interface to, such as the system BIOS or a PXE NBP.
72
+
73
+As well as having a separate addressing scheme, the internal
74
+environment also has a separate stack.
75
+
76
+The transition libraries are:
77
+
78
+a) librm
79
+
80
+librm handles transitions between an external 16-bit real-mode
81
+environment and an internal 32-bit protected-mode environment with
82
+virtual addresses.
83
+
84
+b) libkir
85
+
86
+libkir handles transitions between an external 16-bit real-mode (or
87
+16:16 or 16:32 protected-mode) environment and an internal 16-bit
88
+real-mode (or 16:16 protected-mode) environment.
89
+
90
+c) libpm
91
+
92
+libpm handles transitions between an external 32-bit protected-mode
93
+environment with flat physical addresses and an internal 32-bit
94
+protected-mode environment with virtual addresses.
95
+
96
+The transition libraries handle the transitions required when
97
+Etherboot is started up for the first time, the transitions required
98
+to execute any external code, and the transitions required when
99
+Etherboot exits (if it exits).  When Etherboot provides a PXE API,
100
+they also handle the transitions required when a PXE client makes a
101
+PXE API call to Etherboot.
102
+
103
+Etherboot may use multiple transition libraries.  For example, an
104
+Etherboot ELF image does not require librm for its initial transitions
105
+from prefix to runtime, but may require librm for calling external
106
+real-mode functions.
107
+
108
+3. Setup and initialisation
109
+
110
+Etherboot is conceptually divided into the prefix, the decompressor,
111
+and the runtime image.  (For non-compressed images, the decompressor
112
+is a no-op.)  The complete image comprises all three parts and is
113
+distinct from the runtime image, which exclude the prefix and the
114
+decompressor.
115
+
116
+The prefix does several tasks:
117
+
118
+  Load the complete image into memory.  (For example, the floppy
119
+  prefix issues BIOS calls to load the remainder of the complete image
120
+  from the floppy disk into RAM, and the ISA ROM prefix copies the ROM
121
+  contents into RAM for faster access.)
122
+
123
+  Call the decompressor, if the runtime image is compressed.  This
124
+  decompresses the runtime image.
125
+
126
+  Call the runtime image's setup() routine.  This is a routine
127
+  implemented in assembly code which sets up the internal environment
128
+  so that C code can execute.
129
+
130
+  Call the runtime image's arch_initialise() routine.  This is a
131
+  routine implemented in C which does some basic startup tasks, such
132
+  as initialising the console device, obtaining a memory map and
133
+  relocating the runtime image to high memory.
134
+
135
+  Call the runtime image's arch_main() routine.  This records the exit
136
+  mechanism requested by the prefix and calls main().  (The prefix
137
+  needs to register an exit mechanism because by the time main()
138
+  returns, the memory occupied by the prefix has most likely been
139
+  overwritten.)
140
+
141
+When acting as a PXE ROM, the ROM prefix contains an UNDI loader
142
+routine in addition to its usual code.  The UNDI loader performs a
143
+similar sequence of steps:
144
+
145
+  Load the complete image into memory.
146
+
147
+  Call the decompressor.
148
+
149
+  Call the runtime image's setup() routine.
150
+
151
+  Call the runtime image's arch_initialise() routine.
152
+
153
+  Call the runtime image's install_pxe_stack() routine.
154
+
155
+  Return to caller.
156
+
157
+The runtime image's setup() routine will perform the following steps:
158
+
159
+  Switch to the internal environment using an appropriate transition
160
+  library.  This will record the parameters of the external
161
+  environment.
162
+
163
+  Set up the internal environment: load a stack, and set up a GDT for
164
+  virtual addressing if virtual addressing is to be used.
165
+
166
+  Switch back to the external environment using the transition
167
+  library.  This will record the parameters of the internal
168
+  environment.
169
+
170
+Once the setup() routine has returned, the internal environment has been
171
+set up ready for C code to run.  The prefix can call C routines using
172
+a function from the transition library.
173
+
174
+The runtime image's arch_initialise() routine will perform the
175
+following steps:
176
+
177
+  Zero the bss
178
+
179
+  Initialise the console device(s) and print a welcome message.
180
+
181
+  Obtain a memory map via the INT 15,E820 BIOS call or suitable
182
+  fallback mechanism. [not done if libkir is being used]
183
+
184
+  Relocate the runtime image to the top of high memory. [not done if
185
+  libkir is being used]
186
+
187
+  Install librm to base memory. [done only if librm is being used]
188
+
189
+  Call initialise().
190
+
191
+  Return to the prefix, setting registers to indicate to the prefix
192
+  the new location of the transition library, if applicable.  Which
193
+  registers these are is specific to the transition library being
194
+  used.
195
+
196
+Once the arch_initialise() routine has returned, the prefix will
197
+probably call arch_main().

+ 0
- 1
src/arch/i386/core/callbacks.c View File

@@ -9,7 +9,6 @@
9 9
 #include "etherboot.h"
10 10
 #include "callbacks.h"
11 11
 #include "realmode.h"
12
-#include "segoff.h"
13 12
 #include <stdarg.h>
14 13
 
15 14
 /* Maximum amount of stack data that prefix may request to be passed

+ 4
- 0
src/arch/i386/core/cpu.c View File

@@ -2,6 +2,7 @@
2 2
 #include "stdint.h"
3 3
 #include "string.h"
4 4
 #include "bits/cpu.h"
5
+#include "init.h"
5 6
 
6 7
 
7 8
 /* Standard macro to see if a specific flag is changeable */
@@ -83,4 +84,7 @@ void cpu_setup(void)
83 84
 {
84 85
 	identify_cpu(&cpu_info);
85 86
 }
87
+
88
+INIT_FN ( INIT_CPU, cpu_setup, NULL, NULL );
89
+
86 90
 #endif /* CONFIG_X86_64 */

+ 1
- 0
src/arch/i386/core/elf.c View File

@@ -1,5 +1,6 @@
1 1
 #include "etherboot.h"
2 2
 #include "elf.h"
3
+#include "memsizes.h"
3 4
 
4 5
 
5 6
 #define NAME "Etherboot"

+ 83
- 25
src/arch/i386/core/hooks.c View File

@@ -1,35 +1,93 @@
1
-#include "etherboot.h"
2
-#include "callbacks.h"
3
-#include <stdarg.h>
4
-
5
-void arch_main ( in_call_data_t *data __unused, va_list params __unused )
6
-{
7
-#ifdef PCBIOS
8
-	/* Deallocate base memory used for the prefix, if applicable
9
-	 */
10
-	forget_prefix_base_memory();
1
+#include "stdint.h"
2
+#include "stddef.h"
3
+#include "registers.h"
4
+#include "string.h"
5
+#include "hooks.h"
6
+#include "init.h"
7
+#include "main.h"
8
+#ifdef REALMODE
9
+#include "realmode.h"
11 10
 #endif
12 11
 
13
-}
12
+/* Symbols defined by the linker */
13
+extern char _bss[], _ebss[];
14
+
15
+/*
16
+ * This file provides the basic entry points from assembly code.  See
17
+ * README.i386 for a description of the entry code path.
18
+ *
19
+ * This file is compiled to two different object files: hooks.o and
20
+ * hooks_rm.o.  REALMODE is defined when compiling hooks_rm.o
21
+ *
22
+ */
14 23
 
15
-void arch_relocated_from (unsigned long old_addr )
24
+/*
25
+ * arch_initialise(): perform any required initialisation such as
26
+ * setting up the console device and relocating to high memory.  Note
27
+ * that if we relocate to high memory and the prefix is in base
28
+ * memory, then we will need to install a copy of librm in base memory
29
+ * and adjust retaddr so that we return to the installed copy.
30
+ *
31
+ */
32
+#ifdef REALMODE
33
+void arch_rm_initialise ( struct i386_all_regs *regs,
34
+			  void (*retaddr) (void) )
35
+#else /* REALMODE */
36
+void arch_initialise ( struct i386_all_regs *regs,
37
+		       void (*retaddr) (void) __unused )
38
+#endif /* REALMODE */
16 39
 {
40
+	/* Zero the BSS */
41
+	memset ( _bss, 0, _ebss - _bss );
17 42
 
18
-#ifdef PCBIOS
19
-	/* Deallocate base memory used for the Etherboot runtime,
20
-	 * if applicable
43
+	/* Call all registered initialisation functions.
21 44
 	 */
22
-	forget_runtime_base_memory( old_addr );
23
-#endif
24
-
45
+	call_init_fns ();
25 46
 }
26 47
 
27
-void arch_on_exit ( int exit_status __unused ) 
28
-{
29
-#ifdef PCBIOS
30
-	/* Deallocate the real-mode stack now.  We will reallocate
31
-	 * the stack if are going to use it after this point.
48
+#ifdef REALMODE
49
+
50
+/*
51
+ * arch_rm_main() : call main() and then exit via whatever exit mechanism
52
+ * the prefix requested.
53
+ *
54
+ */
55
+void arch_rm_main ( struct i386_all_regs *regs ) {
56
+	struct i386_all_regs regs_copy;
57
+	void (*exit_fn) ( struct i386_all_regs *regs );
58
+
59
+	/* Take a copy of the registers, because the memory holding
60
+	 * them will probably be trashed by the time main() returns.
32 61
 	 */
33
-	forget_real_mode_stack();
34
-#endif
62
+	regs_copy = *regs;
63
+	exit_fn = ( typeof ( exit_fn ) ) regs_copy.eax;
64
+
65
+	/* Call to main() */
66
+	regs_copy.eax = main();
67
+
68
+	/* Call registered per-object exit functions */
69
+	call_exit_fns ();
70
+
71
+	if ( exit_fn ) {
72
+		/* Prefix requested that we use a particular function
73
+		 * as the exit path, so we call this function, which
74
+		 * must not return.
75
+		 */
76
+		exit_fn ( &regs_copy );
77
+	}
35 78
 }
79
+
80
+#else /* REALMODE */
81
+
82
+/*
83
+ * arch_main() : call main() and return
84
+ *
85
+ */
86
+void arch_main ( struct i386_all_regs *regs ) {
87
+	regs->eax = main();
88
+
89
+	/* Call registered per-object exit functions */
90
+	call_exit_fns ();
91
+};
92
+
93
+#endif /* REALMODE */

+ 5
- 2
src/arch/i386/core/i386_timer.c View File

@@ -10,6 +10,7 @@
10 10
 #include	"etherboot.h"
11 11
 #include	"timer.h"
12 12
 #include	"latch.h"
13
+#include	"init.h"
13 14
 
14 15
 void __load_timer2(unsigned int ticks)
15 16
 {
@@ -40,7 +41,7 @@ static int __timer2_running(void)
40 41
 }
41 42
 
42 43
 #if !defined(CONFIG_TSC_CURRTICKS)
43
-void setup_timers(void)
44
+static void setup_timers(void)
44 45
 {
45 46
 	return;
46 47
 }
@@ -126,7 +127,7 @@ bad_ctc:
126 127
 }
127 128
 
128 129
 static unsigned long clocks_per_tick;
129
-void setup_timers(void)
130
+static void setup_timers(void)
130 131
 {
131 132
 	if (!clocks_per_tick) {
132 133
 		clocks_per_tick = calibrate_tsc();
@@ -189,3 +190,5 @@ int timer2_running(void)
189 190
 }
190 191
 
191 192
 #endif /* RTC_CURRTICKS */
193
+
194
+INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );

+ 0
- 305
src/arch/i386/core/init.S View File

@@ -1,305 +0,0 @@
1
-#include "callbacks.h"
2
-	.equ CR0_PE, 1
3
-	
4
-	.text
5
-	.arch i386
6
-	.section ".prefix", "ax", @progbits
7
-
8
-#undef CODE16
9
-#if defined(PCBIOS)
10
-#define	CODE16
11
-#endif
12
-
13
-/* We have two entry points: "conventional" (at the start of the file)
14
- * and "callback" (at _entry, 2 bytes in).  The "callback" entry
15
- * should be used if the caller wishes to provide a specific opcode.
16
- * It is equivalent to a call to in_call.  Using the "conventional"
17
- * entry point is equivalent to using the "callback" entry point with
18
- * an opcode of EB_OPCODE_MAIN.
19
- *
20
- * Both entry points can be called in either 16-bit real or 32-bit
21
- * protected mode with flat physical addresses.  We detect which mode
22
- * the processor is in and call either in_call or rm_in_call as
23
- * appropriate.  Note that the mode detection code must therefore be
24
- * capable of doing the same thing in either mode, even though the
25
- * machine code instructions will be interpreted differently.
26
- *
27
- * The decompressor will be invoked if necessary to decompress
28
- * Etherboot before attempting to jump to it.
29
- */
30
-
31
-/******************************************************************************
32
- * Entry points and mode detection code
33
- ******************************************************************************
34
- */
35
-
36
-	.code32
37
-/* "Conventional" entry point: caller provides no opcode */
38
-	.globl	_start
39
-_start:
40
-	/* Set flag to indicate conventional entry point used */
41
-	pushl	$0			/* "pushw $0" in 16-bit code */
42
-	/* Fall through to "callback" entry point */
43
-	
44
-/* "Callback" entry point */
45
-	.globl	_entry
46
-_entry:
47
-	
48
-#ifdef CODE16
49
-	/* CPU mode detection code */
50
-	pushl	%eax			/* "pushw %ax" in 16-bit code */
51
-	pushw	%ax			/* "pushl %eax" in 16-bit code */
52
-	movl	%cr0, %eax		/* Test protected mode bit */
53
-	testb	$CR0_PE, %al
54
-	popw	%ax			/* "popl %eax" in 16-bit code */
55
-	popl	%eax			/* "popw %eax" in 16-bit code */
56
-	jz	rmode
57
-#endif /* CODE16 */
58
-
59
-/******************************************************************************
60
- * Entered in protected mode
61
- ******************************************************************************
62
- */
63
-		
64
-	.code32
65
-pmode:
66
-	cmpl	$0, 0(%esp)		/* Conventional entry point used? */
67
-	jne	1f
68
-	/* Entered via conventional entry point: set up stack */
69
-	xchgl	%eax, 4(%esp)		/* %eax = return addr, store %eax */
70
-	movl	%eax, 0(%esp)		/* 0(%esp) = return address */
71
-	movl	$(EB_OPCODE_MAIN|EB_USE_INTERNAL_STACK|EB_SKIP_OPCODE), %eax
72
-	xchgl	%eax, 4(%esp)		/* 4(%esp) = opcode, restore %eax */
73
-1:
74
-	/* Run decompressor if necessary */
75
-	pushl	%eax
76
-	movl	$decompress, %eax
77
-	testl	%eax, %eax
78
-	jz	1f
79
-	call	decompress
80
-1:	popl	%eax
81
-
82
-	/* Make in_call to Etherboot */
83
-	jmp	_prefix_in_call
84
-
85
-/******************************************************************************
86
- * Entered in real mode
87
- ******************************************************************************
88
- */
89
-	
90
-#ifdef CODE16
91
-	.code16
92
-rmode:
93
-	pushw	%ax			/* Padding */
94
-	pushw	%bp
95
-	movw	%sp, %bp
96
-	cmpw	$0, 6(%bp)		/* Conventional entry point used? */
97
-	jne	1f
98
-	/* Entered via conventional entry point: set up stack */
99
-	pushw	%ax
100
-	movw	6(%bp), %ax
101
-	movw	%ax, 2(%bp)		/* Move return address down */
102
-	movl	$(EB_OPCODE_MAIN|EB_USE_INTERNAL_STACK|EB_SKIP_OPCODE), 4(%bp)
103
-	popw	%ax
104
-	popw	%bp
105
-	jmp	2f
106
-1:	/* Entered via callback entry point: do nothing */
107
-	popw	%bp
108
-	popw	%ax
109
-2:
110
-	/* Preserve registers */
111
-	pushw	%ds
112
-	pushl	%eax
113
-	
114
-	/* Run decompressor if necessary.  Decompressor is 32-bit
115
-	 * code, so we must switch to pmode first.  Save and restore
116
-	 * GDT over transition to pmode.
117
-	 */
118
-	movl	$decompress, %eax
119
-	testl	%eax, %eax
120
-	jz	1f
121
-	pushw	%ds
122
-	pushw	%es
123
-	pushw	%fs
124
-	pushw	%gs
125
-	subw	$8, %sp
126
-	pushw	%bp
127
-	movw	%sp, %bp
128
-	sgdt	2(%bp)
129
-	pushw	%ss			/* Store params for _prot_to_real */
130
-	pushw	%cs
131
-	call	_prefix_real_to_prot
132
-	.code32
133
-	call	decompress
134
-	call	_prefix_prot_to_real
135
-	.code16
136
-	popw	%ax			/* skip */
137
-	popw	%ax			/* skip */
138
-	lgdt	2(%bp)
139
-	popw	%bp
140
-	addw	$8, %sp
141
-	popw	%gs
142
-	popw	%fs
143
-	popw	%es
144
-	popw	%ds
145
-1:
146
-
147
-	/* Set rm_etherboot_location */
148
-	xorl	%eax, %eax
149
-	movw	%cs, %ax
150
-	movw	%ax, %ds
151
-	shll	$4, %eax
152
-	addl	$_prefix_size, %eax
153
-	movl	%eax, _prefix_rm_etherboot_location
154
-
155
-	/* Restore registers */
156
-	popl	%eax
157
-	popw	%ds
158
-
159
-	/* Make real-mode in_call to Etherboot */
160
-	jmp	_prefix_rm_in_call
161
-#endif /* CODE16 */
162
-
163
-/******************************************************************************
164
- * Utility routines that can be called by the "prefix".
165
- ******************************************************************************
166
- */
167
-
168
-#ifdef CODE16
169
-
170
-/* Prelocate code: either to an area at the top of free base memory.
171
- * Switch stacks to use the stack within the resulting
172
- * Etherboot image.
173
- *
174
- * On entry, %cs:0000 must be the start of the prefix: this is used to
175
- * locate the code to be copied.
176
- *
177
- * This routine takes a single word parameter: the number of bytes to
178
- * be transferred from the old stack to the new stack (excluding the
179
- * return address and this parameter itself, which will always be
180
- * copied).  If this value is negative, the stacks will not be
181
- * switched.
182
- *
183
- * Control will "return" to the appropriate point in the relocated
184
- * image.
185
- */
186
-
187
-#define PRELOC_PRESERVE ( 20 )
188
-#define PRELOC_OFFSET_RETADDR ( PRELOC_PRESERVE )
189
-#define PRELOC_OFFSET_RETADDR_E ( PRELOC_OFFSET_RETADDR + 4 )
190
-#define PRELOC_OFFSET_COPY ( PRELOC_OFFSET_RETADDR_E )
191
-#define PRELOC_OFFSET_COPY_E ( PRELOC_OFFSET_COPY + 2 )
192
-
193
-#define PRELOC_ALWAYS_COPY ( PRELOC_OFFSET_COPY_E )
194
-	
195
-	.code16
196
-	.globl	prelocate
197
-prelocate:
198
-	/* Pad to allow for expansion of return address */
199
-	pushw	%ax
200
-	
201
-	/* Preserve registers */
202
-	pushaw
203
-	pushw	%ds
204
-	pushw	%es
205
-	
206
-	/* Claim an area of base memory from the BIOS and put the
207
-	 * payload there.
208
-	 */
209
-	movw	$0x40, %bx
210
-	movw	%bx, %es
211
-	movw	%es:(0x13), %bx		/* FBMS in kb to %ax */
212
-	shlw	$6, %bx			/* ... in paragraphs */
213
-	subw	$_image_size_pgh, %bx	/* Subtract space for image */
214
-	shrw	$6, %bx			/* Round down to nearest kb */
215
-	movw	%bx, %es:(0x13)		/* ...and claim memory from BIOS */
216
-	shlw	$6, %bx
217
-
218
-	/* At this point %bx contains the segment address for the
219
-	 * start of the image (image = prefix + runtime).
220
-	 */
221
-
222
-	/* Switch stacks */
223
-	movw	%ss, %ax
224
-	movw	%ax, %ds
225
-	movw	%sp, %si		/* %ds:si = current %ss:sp */
226
-	movw	%ss:PRELOC_OFFSET_COPY(%si), %cx
227
-	testw	%cx, %cx
228
-	js	1f
229
-	leaw	_stack_offset_pgh(%bx), %ax /* %ax = new %ss */
230
-	movw	%ax, %es
231
-	movw	$_stack_size, %di
232
-	addw	$PRELOC_ALWAYS_COPY, %cx
233
-	subw	%cx, %di		/* %es:di = new %ss:sp */
234
-	movw	%ax, %ss		/* Set new %ss:sp */
235
-	movw	%di, %sp
236
-	cld
237
-	rep movsb			/* Copy stack contents */
238
-1:	
239
-
240
-	/* Do the image copy backwards, since if there's overlap with
241
-	 * a forward copy then it means we're going to get trashed
242
-	 * during the copy anyway...
243
-	 */
244
-	pushal				/* Preserve 32-bit registers */
245
-	movw	%bx, %es		/* Destination base for copy */
246
-	pushw	%cs
247
-	popw	%ds			/* Source base for copy */
248
-	movl	$_verbatim_size-1, %ecx	/* Offset to last byte */
249
-	movl	%ecx, %esi
250
-	movl	%ecx, %edi
251
-	incl	%ecx			/* Length */
252
-	std				/* Backwards copy of binary */
253
-	ADDR32 rep movsb
254
-	cld
255
-	popal				/* Restore 32-bit registers */
256
-
257
-	/* Store (%bx<<4) as image_basemem to be picked up by
258
-	 * basemem.c.  Also store image_size, since there's no other
259
-	 * way that we can later know how much memory we allocated.
260
-	 * (_zfile_size is unavailable when rt2 is linked).
261
-	 */
262
-	pushl	%eax
263
-	xorl	%eax, %eax
264
-	movw	%bx, %ax
265
-	shll	$4, %eax
266
-	movl	%eax, %es:_prefix_image_basemem
267
-	movl	$_image_size, %es:_prefix_image_basemem_size
268
-	popl	%eax
269
-
270
-	/* Expand original near return address into far return to new
271
-	 * code location.
272
-	 */
273
-	movw	%sp, %bp
274
-	xchgw	%bx, (PRELOC_OFFSET_RETADDR+2)(%bp)
275
-	movw	%bx, (PRELOC_OFFSET_RETADDR+0)(%bp)
276
-
277
-	/* Restore registers and return */
278
-	popw	%es
279
-	popw	%ds
280
-	popaw
281
-	lret				/* Jump to relocated code */
282
-
283
-	/* Utility routine to free base memory allocated by prelocate.
284
-	 * Ensure that said memory is not in use (e.g. for the CPU
285
-	 * stack) before calling this routine.
286
-	 */
287
-	.globl deprelocate
288
-deprelocate:	
289
-	/* Claim an area of base memory from the BIOS and put the
290
-	 * payload there.
291
-	 */
292
-	pushw	%ax
293
-	pushw	%es
294
-	movw	$0x40, %ax
295
-	movw	%ax, %es
296
-	movw	%es:(0x13), %ax		/* FBMS in kb to %ax */
297
-	shlw	$6, %ax			/* ... in paragraphs */
298
-	addw	$_image_size_pgh+0x40-1, %ax /* Add space for image and... */
299
-	shrw	$6, %ax			/* ...round up to nearest kb */
300
-	movw	%ax, %es:(0x13)		/* Give memory back to BIOS */
301
-	popw	%es
302
-	popw	%ax
303
-	ret
304
-	
305
-#endif /* CODE16 */

+ 27
- 0
src/arch/i386/core/pxe_callbacks.c View File

@@ -3,6 +3,31 @@
3 3
  * an NBP to the PXE stack and for starting an NBP from the PXE stack.
4 4
  */
5 5
 
6
+#warning "pxe_callbacks.c is temporarily broken"
7
+
8
+void xstartpxe ( void ) {
9
+}
10
+
11
+void install_pxe_stack ( void ) {
12
+}
13
+
14
+void remove_pxe_stack ( void ) {
15
+}
16
+
17
+void hook_pxe_stack ( void ) {
18
+}
19
+
20
+void unhook_pxe_stack ( void ) {
21
+}
22
+
23
+void pxe_in_call ( void ) {
24
+}
25
+
26
+void use_undi_ds_for_rm_stack ( void ) {
27
+}
28
+
29
+#if 0
30
+
6 31
 #ifdef PXE_EXPORT
7 32
 
8 33
 #include "etherboot.h"
@@ -362,3 +387,5 @@ __asm__ ( ".globl _pxe_stack_t_size" );
362 387
 __asm__ ( ".equ _pxe_stack_t_size, 0" );
363 388
 
364 389
 #endif /* PXE_EXPORT */
390
+
391
+#endif /* 0 */

+ 21
- 129
src/arch/i386/core/realmode.c View File

@@ -3,146 +3,38 @@
3 3
  * Initial version by Michael Brown <mbrown@fensystems.co.uk>, January 2004.
4 4
  */
5 5
 
6
-#include "etherboot.h"
7 6
 #include "realmode.h"
8
-#include "segoff.h"
9 7
 
10
-#define RM_STACK_SIZE ( 0x1000 )
11
-
12
-/* gcc won't let us use extended asm outside a function (compiler
13
- * bug), ao we have to put these asm statements inside a dummy
14
- * function.
15
- */
16
-static void work_around_gcc_bug ( void ) __attribute__ ((used));
17
-static void work_around_gcc_bug ( void ) {
18
-	/* Export _real_mode_stack_size as absolute linker symbol */
19
-	__asm__ ( ".globl _real_mode_stack_size" );
20
-	__asm__ ( ".equ _real_mode_stack_size, %c0" : : "i" (RM_STACK_SIZE) );
21
-}
22
-
23
-/* While Etherboot remains in base memory the real-mode stack is
24
- * placed in the Etherboot main stack.  The first allocation or
25
- * deallocation of base memory will cause a 'proper' real-mode stack
26
- * to be allocated.  This will happen before Etherboot is relocated to
27
- * high memory.
28
- */
29
-uint32_t real_mode_stack = 0;
30
-size_t real_mode_stack_size = RM_STACK_SIZE;
31
-int lock_real_mode_stack = 0;	/* Set to make stack immobile */
32
-
33
-/* Make a call to a real-mode code block.
34
- */
35
-
36
-/* These is the structure that exists on the stack as the paramters
37
- * passed in to _real_call.  We pass a pointer to this struct to
38
- * prepare_real_call(), to save stack space.
8
+/*
9
+ * Copy data to/from base memory.
10
+ *
39 11
  */
40
-typedef struct {
41
-	void *fragment;
42
-	int fragment_len;
43
-	void *in_stack;
44
-	int in_stack_len;
45
-	void *out_stack;
46
-	int out_stack_len;
47
-} real_call_params_t;
48 12
 
49
-uint32_t prepare_real_call ( real_call_params_t *p,
50
-			     int local_stack_len, char *local_stack ) {
51
-	char *stack_base;
52
-	char *stack_end;
53
-	char *stack;
54
-	char *s;
55
-	prot_to_real_params_t *p2r_params;
56
-	real_to_prot_params_t *r2p_params;
13
+#ifdef KEEP_IT_REAL
57 14
 
58
-	/* Work out where we're putting the stack */
59
-	if ( virt_to_phys(local_stack) < 0xa0000 ) {
60
-		/* Current stack is in base memory.  We can therefore
61
-		 * use it directly, with a constraint on the size that
62
-		 * we don't know; assume that we can use up to
63
-		 * real_mode_stack_size.  (Not a valid assumption, but
64
-		 * it will do).
65
-		 */
66
-		stack_end = local_stack + local_stack_len;
67
-		stack_base = stack_end - real_mode_stack_size;
68
-	} else {
69
-		if (!real_mode_stack) {
70
-			allot_real_mode_stack();
71
-		}
72
-		/* Use the allocated real-mode stack in base memory.
73
-		 * This has fixed start and end points.
74
-		 */
75
-		stack_base = phys_to_virt(real_mode_stack);
76
-		stack_end = stack_base + real_mode_stack_size;
77
-	}
78
-	s = stack = stack_end - local_stack_len;
15
+void memcpy_to_real ( segoff_t dest, void *src, size_t n ) {
79 16
 
80
-	/* Compile input stack and trampoline code to stack */
81
-	if ( p->in_stack_len ) {
82
-		memcpy ( s, p->in_stack, p->in_stack_len );
83
-		s += p->in_stack_len;
84
-	}
85
-	memcpy ( s, _prot_to_real_prefix, prot_to_real_prefix_size );
86
-	s += prot_to_real_prefix_size;
87
-	p2r_params = (prot_to_real_params_t*) ( s - sizeof(*p2r_params) );
88
-	memcpy ( s, p->fragment, p->fragment_len );
89
-	s += p->fragment_len;
90
-	memcpy ( s, _real_to_prot_suffix, real_to_prot_suffix_size );
91
-	s += real_to_prot_suffix_size;
92
-	r2p_params = (real_to_prot_params_t*) ( s - sizeof(*r2p_params) );
17
+}
93 18
 
94
-	/* Set parameters within compiled stack */
95
-	p2r_params->ss = p2r_params->cs = SEGMENT ( stack_base );
96
-	p2r_params->esp = virt_to_phys ( stack );
97
-	p2r_params->r2p_params = virt_to_phys ( r2p_params );
98
-	r2p_params->out_stack = ( p->out_stack == NULL ) ?
99
-		0 : virt_to_phys ( p->out_stack );
100
-	r2p_params->out_stack_len = p->out_stack_len;
19
+void memcpy_from_real ( void *dest, segoff_t src, size_t n ) {
101 20
 
102
-	return virt_to_phys ( stack + p->in_stack_len );
103 21
 }
104 22
 
23
+#endif /* KEEP_IT_REAL */
105 24
 
106
-/* Parameters are not genuinely unused; they are passed to
107
- * prepare_real_call() as part of a real_call_params_t struct.
108
- */
109
-uint16_t _real_call ( void *fragment, int fragment_len,
110
-		      void *in_stack __unused, int in_stack_len,
111
-		      void *out_stack __unused, int out_stack_len __unused ) {
112
-	uint16_t retval;
113 25
 
114
-	/* This code is basically equivalent to
115
-	 *
116
-	 *	uint32_t trampoline;
117
-	 *	char local_stack[ in_stack_len + prot_to_real_prefix_size +
118
-	 *			  fragment_len + real_to_prot_suffix_size ];
119
-	 *	trampoline = prepare_real_call ( &fragment, local_stack );
120
-	 *	__asm__ ( "call _virt_to_phys\n\t"
121
-	 *		  "call %%eax\n\t"
122
-	 *		  "call _phys_to_virt\n\t"
123
-	 *		  : "=a" (retval) : "0" (trampoline) );
124
-	 *
125
-	 * but implemented in assembly to avoid problems with not
126
-	 * being certain exactly how gcc handles %esp.
127
-	 */
26
+#define RM_STACK_SIZE ( 0x1000 )
128 27
 
129
-	__asm__ ( "pushl %%ebp\n\t"
130
-		  "movl  %%esp, %%ebp\n\t"	/* %esp preserved via %ebp */
131
-		  "subl  %%ecx, %%esp\n\t"	/* space for inline RM stack */
132
-		  "pushl %%esp\n\t"		/* set up RM stack */
133
-		  "pushl %%ecx\n\t"
134
-		  "pushl %%eax\n\t"
135
-		  "call  prepare_real_call\n\t"	/* %eax = trampoline addr */
136
-		  "addl  $12, %%esp\n\t"
137
-		  "call  _virt_to_phys\n\t"	/* switch to phys addr */
138
-		  "call  *%%eax\n\t"		/* call to trampoline */
139
-		  "call  _phys_to_virt\n\t"	/* switch to virt addr */
140
-		  "movl  %%ebp, %%esp\n\t"	/* restore %esp & %ebp */
141
-		  "popl  %%ebp\n\t"
142
-		  : "=a" ( retval )
143
-		  : "0" ( &fragment )
144
-		  , "c" ( ( ( in_stack_len + prot_to_real_prefix_size +
145
-			      fragment_len + real_to_prot_suffix_size )
146
-			    + 0x3 ) & ~0x3 ) );
147
-	return retval;
28
+/* gcc won't let us use extended asm outside a function (compiler
29
+ * bug), ao we have to put these asm statements inside a dummy
30
+ * function.
31
+ */
32
+static void work_around_gcc_bug ( void ) __attribute__ ((used));
33
+static void work_around_gcc_bug ( void ) {
34
+	/* Export _real_mode_stack_size as absolute linker symbol */
35
+	__asm__ ( ".globl real_mode_stack_size" );
36
+	__asm__ ( ".equ real_mode_stack_size, %c0" : : "i" (RM_STACK_SIZE) );
148 37
 }
38
+
39
+char *real_mode_stack;
40
+int lock_real_mode_stack;

+ 0
- 564
src/arch/i386/core/realmode_asm.S View File

@@ -31,570 +31,6 @@
31 31
 #define	LJMPI(x)	ljmp	x
32 32
 #endif
33 33
 
34
-/****************************************************************************
35
- * REAL-MODE CALLBACK INTERFACE
36
- *
37
- * This must be copied down to base memory in order for external
38
- * programs to be able to make calls in to Etherboot.  Store the
39
- * current physical address of Etherboot (i.e. virt_to_phys(_text)) in
40
- * (uint32_t)rm_etherboot_location, then copy
41
- * (uint16_t)rm_callback_interface_size bytes starting at
42
- * &((void)rm_callback_interface).
43
- *
44
- * There are two defined entry points:
45
- *   Offset RM_IN_CALL     = 0		Near call entry point
46
- *   Offset RM_IN_CALL_FAR = 2		Far call entry point
47
- *
48
- * Note that the routines _prot_to_real and _real_to_prot double as
49
- * trampoline fragments for external calls (calls from Etherboot to
50
- * real-mode code).  _prot_to_real does not automatically re-enable
51
- * interrupts; this is to allow for the potential of using Etherboot
52
- * code as an ISR.  _real_to_prot does automatically disable
53
- * interrupts, since we don't have a protected-mode IDT.
54
- ****************************************************************************
55
- */
56
-
57
-	.globl	rm_callback_interface
58
-	.code16
59
-rm_callback_interface:
60
-	.globl	_rm_in_call
61
-_rm_in_call:
62
-	jmp	_real_in_call
63
-	.globl	_rm_in_call_far
64
-_rm_in_call_far:
65
-	jmp	_real_in_call_far
66
-
67
-/****************************************************************************
68
- * _real_in_call
69
- *
70
- * Parameters:
71
- *   16-bit real-mode near/far return address (implicit from [l]call
72
- *   to routine) Other parameters as for _in_call_far().
73
- *
74
- * This routine will convert the 16-bit real-mode far return address
75
- * to a 32-bit real-mode far return address, switch to protected mode
76
- * using _real_to_prot and call in to _in_call_far.
77
- ****************************************************************************
78
- */
79
-
80
-#define RIC_PRESERVE ( 8 )
81
-#define RIC_OFFSET_CALLADDR ( RIC_PRESERVE )
82
-#define RIC_OFFSET_CALLADDR_E ( RIC_OFFSET_CALLADDR + 4 )
83
-#define RIC_OFFSET_CONTADDR ( RIC_OFFSET_CALLADDR_E )
84
-#define RIC_OFFSET_CONTADDR_E ( RIC_OFFSET_CONTADDR + 4 )
85
-#define RIC_OFFSET_OPCODE ( RIC_OFFSET_CONTADDR_E )
86
-#define RIC_OFFSET_OPCODE_E ( RIC_OFFSET_OPCODE + 4 )
87
-#define RIC_OFFSET_SEG_REGS ( RIC_OFFSET_OPCODE_E )
88
-#define RIC_OFFSET_SEG_REGS_E ( RIC_OFFSET_SEG_REGS + ( NUM_SEG_REGS * 2 ) )
89
-#define RIC_OFFSET_PAD ( RIC_OFFSET_SEG_REGS_E )
90
-#define RIC_OFFSET_PAD_E ( RIC_OFFSET_PAD + 2 )
91
-#define RIC_OFFSET_FLAGS ( RIC_OFFSET_PAD_E )
92
-#define RIC_OFFSET_FLAGS_E ( RIC_OFFSET_FLAGS + 2 )
93
-#define RIC_OFFSET_RETADDR ( RIC_OFFSET_FLAGS_E )
94
-#define RIC_OFFSET_RETADDR_E ( RIC_OFFSET_RETADDR + 4 )
95
-#define RIC_OFFSET_ORIG_OPCODE ( RIC_OFFSET_RETADDR_E )
96
-#define RIC_INSERT_LENGTH ( RIC_OFFSET_OPCODE_E - RIC_OFFSET_CALLADDR )
97
-	
98
-	.code16
99
-_real_in_call:
100
-	/* Expand near return address to far return address
101
-	 */
102
-	pushw	%ax		/* Extend stack, store %ax */
103
-	pushfw
104
-	pushw	%bp
105
-	movw	%sp, %bp
106
-	movw	%cs, %ax
107
-	xchgw	%ax, 6(%bp)
108
-	xchgw	%ax, 4(%bp)	/* also restores %ax */
109
-	popw	%bp
110
-	popfw
111
-	/* Fall through to _real_in_call_far */
112
-	
113
-_real_in_call_far:
114
-	/* Store flags and pad */
115
-	pushfw
116
-	pushw	%ax
117
-
118
-	/* Store segment registers.  Order matches that of seg_regs_t */
119
-	pushw	%gs
120
-	pushw	%fs
121
-	pushw	%es
122
-	pushw	%ds
123
-	pushw	%ss
124
-	pushw	%cs
125
-
126
-	/* Switch to protected mode */
127
-	call _real_to_prot
128
-	.code32
129
-
130
-	/* Allow space for expanded stack */
131
-	subl	$RIC_INSERT_LENGTH, %esp
132
-	
133
-	/* Store temporary registers */
134
-	pushl	%ebp
135
-	pushl	%eax
136
-
137
-	/* Copy opcode, set EB_CALL_FROM_REAL_MODE and EP_SKIP_OPCODE.
138
-	 * Copy it because _in_call() and i386_in_call() expect it at
139
-	 * a fixed position, not as part of the va_list.
140
-	 */
141
-	movl	RIC_OFFSET_ORIG_OPCODE(%esp), %eax
142
-	orl	$(EB_CALL_FROM_REAL_MODE|EB_SKIP_OPCODE), %eax
143
-	movl	%eax, RIC_OFFSET_OPCODE(%esp)
144
-	
145
-	/* Set up call and return addresses */
146
-	call	1f
147
-1:	popl	%ebp
148
-	subl	$1b, %ebp			/* %ebp = offset */
149
-	movl	rm_etherboot_location(%ebp), %eax  /* Etherboot phys addr */
150
-	subl	$_text, %eax
151
-	addl	$_in_call, %eax			/* _in_call phys addr */
152
-	movl	%eax, RIC_OFFSET_CALLADDR(%esp)
153
-	leal	2f(%ebp), %eax			/* continuation address */
154
-	movl	%eax, RIC_OFFSET_CONTADDR(%esp)
155
-	
156
-	/* Restore temporary registers */
157
-	popl	%eax
158
-	popl	%ebp
159
-
160
-	/* Call to _in_call */
161
-	ret
162
-	/* opcode will be popped automatically thanks to EB_SKIP_OPCODE */
163
-
164
-2:	/* Continuation point */
165
-	call	_prot_to_real			/* Return to real mode */
166
-	/* Note: the first two words of our segment register store
167
-	 * happens to be exactly what we need to pass as parameters to
168
-	 * _prot_to_real.
169
-	 */
170
-	.code16
171
-	popw	%ds				/* Restore segment registers */
172
-	popw	%ds				/* (skip cs&ss since these   */
173
-	popw	%ds				/* have already been set by  */
174
-	popw	%es				/* _prot_to_real	     */
175
-	popw	%fs
176
-	popw	%gs
177
-	addw	$2, %sp				/* skip pad */
178
-
179
-	/* Check for EB_SKIP_OPCODE */
180
-	pushw	%bp
181
-	movw	%sp, %bp
182
-	testl	$EB_SKIP_OPCODE, 6(%bp)
183
-	popw	%bp
184
-	jnz	1f
185
-	/* Normal return */
186
-	popfw					/* Restore interrupt status */
187
-	lret					/* Back to caller */
188
-1:	/* Return and skip opcode */
189
-	popfw
190
-	lret	$4
191
-
192
-/****************************************************************************
193
- * rm_etherboot_location: the current physical location of Etherboot.
194
- * Needed so that real-mode callback routines can locate Etherboot.
195
- ****************************************************************************
196
- */
197
-	.globl rm_etherboot_location
198
-rm_etherboot_location:	.long 0
199
-		
200
-/****************************************************************************
201
- * _prot_to_real_prefix
202
- *
203
- * Trampoline fragment.  Switch from 32-bit protected mode with flat
204
- * physical addresses to 16-bit real mode.  Store registers in the
205
- * trampoline for restoration by _real_to_prot_suffix.  Switch to
206
- * stack in base memory.
207
- ****************************************************************************
208
- */
209
-	
210
-	.globl _prot_to_real_prefix
211
-	.code32
212
-_prot_to_real_prefix:
213
-	/* Registers to preserve */
214
-	pushl	%ebx
215
-	pushl	%esi
216
-	pushl	%edi
217
-	pushl	%ebp
218
-
219
-	/* Calculate offset */
220
-	call	1f
221
-1:	popl	%ebp
222
-	subl	$1b, %ebp		/* %ebp = offset for labels in p2r*/
223
-
224
-	/* Preserve registers and return address in r2p_params */
225
-	movl	p2r_r2p_params(%ebp), %ebx
226
-	subl	$r2p_params, %ebx	/* %ebx = offset for labels in r2p */
227
-	popl	r2p_ebp(%ebx)
228
-	popl	r2p_edi(%ebx)
229
-	popl	r2p_esi(%ebx)
230
-	popl	r2p_ebx(%ebx)
231
-	popl	r2p_ret_addr(%ebx)
232
-	movl	%esp, r2p_esp(%ebx)
233
-
234
-	/* Switch stacks */
235
-	movl	p2r_esp(%ebp), %esp
236
-
237
-	/* Switch to real mode */
238
-	pushl	p2r_segments(%ebp)
239
-	call	_prot_to_real
240
-	.code16
241
-	addw	$4, %sp
242
-		
243
-	/* Fall through to next trampoline fragment */
244
-	jmp	_prot_to_real_prefix_end
245
-	
246
-/****************************************************************************
247
- * _prot_to_real
248
- *
249
- * Switch from 32-bit protected mode with flat physical addresses to
250
- * 16-bit real mode.  Stack and code must be in base memory when
251
- * called.  %cs, %ss, %eip, %esp are changed to real-mode values,
252
- * other segment registers are destroyed, all other registers are
253
- * preserved.  Interrupts are *not* enabled.
254
- *
255
- * Parameters:
256
- *   %cs		Real-mode code segment (word)
257
- *   %ss		Real-mode stack segment (word)
258
- ****************************************************************************
259
- */
260
-
261
-#define P2R_PRESERVE ( 12 )
262
-#define P2R_OFFSET_RETADDR ( P2R_PRESERVE )
263
-#define P2R_OFFSET_RETADDR_E ( P2R_OFFSET_RETADDR + 4 )
264
-#define P2R_OFFSET_CS ( P2R_OFFSET_RETADDR_E )
265
-#define P2R_OFFSET_CS_E ( P2R_OFFSET_CS + 2 )
266
-#define P2R_OFFSET_SS ( P2R_OFFSET_CS_E )
267
-#define P2R_OFFSET_SS_E ( P2R_OFFSET_SS + 2 )
268
-
269
-	.globl _prot_to_real
270
-	.code32
271
-_prot_to_real:
272
-	/* Preserve registers */
273
-	pushl	%ebp
274
-	pushl	%ebx
275
-	pushl	%eax
276
-	
277
-	/* Calculate offset */
278
-	call	1f
279
-1:	popl	%ebp
280
-	subl	$1b, %ebp		/* %ebp = offset for labels in p2r*/
281
-
282
-	/* Set up GDT with real-mode limits and appropriate bases for
283
-	 * real-mode %cs and %ss.  Set up protected-mode continuation
284
-	 * point on stack.
285
-	 */
286
-	/* Fixup GDT */
287
-	leal	p2r_gdt(%ebp), %eax
288
-	movl	%eax, p2r_gdt_addr(%ebp)
289
-
290
-	/* Calculate CS base address: set GDT code segment, adjust
291
-	 * return address, set up continuation address on stack.
292
-	 */
293
-	movzwl	P2R_OFFSET_CS(%esp), %eax
294
-	shll	$4, %eax
295
-	/* Change return address to real-mode far address */
296
-	subl	%eax, P2R_OFFSET_RETADDR(%esp)
297
-	movl	%eax, %ebx
298
-	shrl	$4, %ebx
299
-	movw	%bx, (P2R_OFFSET_RETADDR+2)(%esp)
300
-	/* First real mode address */
301
-	movl	%eax, %ebx
302
-	shrl	$4, %ebx
303
-	pushw	%bx
304
-	leal	3f(%ebp), %ebx
305
-	subl	%eax, %ebx
306
-	pushw	%bx
307
-	/* Continuation address */
308
-	pushl	$(p2r_rmcs - p2r_gdt)
309
-	leal	2f(%ebp), %ebx
310
-	subl	%eax, %ebx
311
-	pushl	%ebx
312
-	/* Code segment in GDT */
313
-	movw	%ax, (p2r_rmcs+2)(%ebp)
314
-	shrl	$16, %eax			/* Remainder of cs base addr */
315
-	movb	%al, (p2r_rmcs+4)(%ebp)
316
-	movb	%ah, (p2r_rmcs+7)(%ebp)
317
-
318
-	/* Calculate SS base address: set GDT data segment, retain to
319
-	 * use for adjusting %esp.
320
-	 */
321
-	movzwl	(12+P2R_OFFSET_SS)(%esp), %eax	/* Set ss base address */
322
-	shll	$4, %eax
323
-	movw	%ax, (p2r_rmds+2)(%ebp)
324
-	movl	%eax, %ebx
325
-	shrl	$16, %ebx
326
-	movb	%bl, (p2r_rmds+4)(%ebp)
327
-	movb	%bh, (p2r_rmds+7)(%ebp)
328
-
329
-	/* Load GDT */
330
-	lgdt	p2r_gdt(%ebp)
331
-	/* Reload all segment registers and adjust %esp */
332
-	movw	$(p2r_rmds - p2r_gdt), %bx /* Pmode DS */
333
-	movw	%bx, %ss
334
-	subl	%eax, %esp		/* %esp now less than 0x10000 */
335
-	movw	%bx, %ds
336
-	movw	%bx, %es
337
-	movw	%bx, %fs
338
-	movw	%bx, %gs
339
-	lret				/* %cs:eip */
340
-2:	/* Segment registers now have 16-bit limits. */
341
-	.code16
342
-
343
-	/* Switch to real mode */
344
-	movl	%cr0, %ebx
345
-	andb	$0!CR0_PE, %bl
346
-	movl	%ebx, %cr0
347
-
348
-	/* Make intersegment jmp to flush the processor pipeline
349
-	 * and reload %cs:%eip (to clear upper 16 bits of %eip).
350
-	 */
351
-	lret
352
-3:		
353
-	
354
-	/* Load real-mode segment value to %ss.  %sp already OK */
355
-	shrl	$4, %eax
356
-	movw	%ax, %ss
357
-
358
-	/* Restore registers */
359
-	popl	%eax
360
-	popl	%ebx
361
-	popl	%ebp
362
-
363
-	/* Return to caller in real-mode */
364
-	lret
365
-
366
-#ifdef FLATTEN_REAL_MODE
367
-#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x8f
368
-#else
369
-#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x00
370
-#endif
371
-
372
-p2r_gdt:
373
-p2r_gdtarg:
374
-p2r_gdt_limit:		.word p2r_gdt_end - p2r_gdt - 1
375
-p2r_gdt_addr:		.long 0
376
-p2r_gdt_padding:	.word 0
377
-p2r_rmcs:
378
-	/* 16 bit real mode code segment */
379
-	.word	0xffff,(0&0xffff)
380
-	.byte	(0>>16),0x9b,RM_LIMIT_16_19__AVL__SIZE__GRANULARITY,(0>>24)
381
-p2r_rmds:
382
-	/* 16 bit real mode data segment */
383
-	.word	0xffff,(0&0xffff)
384
-	.byte	(0>>16),0x93,RM_LIMIT_16_19__AVL__SIZE__GRANULARITY,(0>>24)
385
-p2r_gdt_end:
386
-
387
-	/* This is the end of the trampoline prefix code.  When used
388
-	 * as a prefix, fall through to the following code in the
389
-	 * trampoline.
390
-	 */
391
-p2r_params: /* Structure must match prot_to_real_params_t in realmode.h */
392
-p2r_esp:	.long 0
393
-p2r_segments:
394
-p2r_cs:		.word 0
395
-p2r_ss:		.word 0
396
-p2r_r2p_params:	.long 0
397
-	.globl	_prot_to_real_prefix_end
398
-_prot_to_real_prefix_end:
399
-	
400
-	.globl	_prot_to_real_prefix_size
401
-	.equ	_prot_to_real_prefix_size, _prot_to_real_prefix_end - _prot_to_real_prefix
402
-	.globl	prot_to_real_prefix_size
403
-prot_to_real_prefix_size:	
404
-	.word	_prot_to_real_prefix_size
405
-	
406
-/****************************************************************************
407
- * _real_to_prot_suffix
408
- *
409
- * Trampoline fragment.  Switch from 16-bit real-mode to 32-bit
410
- * protected mode with flat physical addresses.  Copy returned stack
411
- * parameters to output_stack.  Restore registers preserved by
412
- * _prot_to_real_prefix.  Restore stack to previous location.
413
- ****************************************************************************
414
- */
415
-
416
-	.globl _real_to_prot_suffix
417
-	.code16
418
-_real_to_prot_suffix:
419
-
420
-	/* Switch to protected mode */
421
-	call	_real_to_prot
422
-	.code32
423
-
424
-	/* Calculate offset */
425
-	call	1f
426
-1:	popl	%ebp
427
-	subl	$1b, %ebp		/* %ebp = offset for labels in r2p */
428
-
429
-	/* Copy stack to out_stack */
430
-	movl	r2p_out_stack(%ebp), %edi
431
-	movl	r2p_out_stack_len(%ebp), %ecx
432
-	movl	%esp, %esi
433
-	cld
434
-	rep movsb
435
-
436
-	/* Switch back to original stack */
437
-	movl	r2p_esp(%ebp), %esp
438
-
439
-	/* Restore registers and return */
440
-	pushl	r2p_ret_addr(%ebp)	/* Set up return address on stack */
441
-	movl	r2p_ebx(%ebp), %ebx
442
-	movl	r2p_esi(%ebp), %esi
443
-	movl	r2p_edi(%ebp), %edi
444
-	movl	r2p_ebp(%ebp), %ebp
445
-	ret
446
-
447
-/****************************************************************************
448
- * _real_to_prot
449
- *
450
- * Switch from 16-bit real-mode to 32-bit protected mode with flat
451
- * physical addresses.  All segment registers are destroyed, %eip and
452
- * %esp are changed to flat physical values, all other registers are
453
- * preserved.  Interrupts are disabled.
454
- *
455
- * Parameters: none
456
- ****************************************************************************
457
- */
458
-
459
-#define R2P_PRESERVE ( 12 )
460
-#define R2P_OFFSET_RETADDR ( R2P_PRESERVE )
461
-#define R2P_OFFSET_ORIG_RETADDR ( R2P_OFFSET_RETADDR + 2 )
462
-
463
-	.globl _real_to_prot
464
-	.code16		
465
-_real_to_prot:
466
-	/* Disable interrupts */
467
-	cli
468
-	/* zero extend the return address */
469
-	pushw	$0
470
-
471
-	/* Preserve registers */
472
-	pushl	%ebp
473
-	pushl	%ebx
474
-	pushl	%eax
475
-
476
-	/* Convert 16-bit real-mode near return address to
477
-	 * 32-bit pmode physical near return address
478
-	 */
479
-	movw	%sp, %bp
480
-	xorl	%ebx, %ebx
481
-	push	%cs
482
-	popw	%bx
483
-	movw	%bx, %ds
484
-	shll	$4, %ebx
485
-	movzwl	%ss:R2P_OFFSET_ORIG_RETADDR(%bp), %eax
486
-	addl	%ebx, %eax
487
-	movl	%eax, %ss:(R2P_OFFSET_RETADDR)(%bp)
488
-
489
-	/* Store the code segment physical base address in %ebp */
490
-	movl	%ebx, %ebp
491
-
492
-	/* Find the offset within the code segment that I am running at */
493
-	xorl	%ebx, %ebx
494
-	call	1f
495
-1:	popw	%bx
496
-
497
-	/* Set up GDT */
498
-	leal	(r2p_gdt-1b)(%bx), %eax	/* %ds:ebx = %ds:bx = &(r2p_gdt) */
499
-	addl	%ebp, %eax		/* %eax = &r2p_gdt (physical) */
500
-	movl	%eax, %ds:(r2p_gdt-1b+2)(%bx) /* Set phys. addr. in r2p_gdt */
501
-
502
-	/* Compute the first protected mode physical address */
503
-	leal	(2f-1b)(%bx), %eax
504
-	addl	%ebp, %eax
505
-	movl	%eax, %ds:(r2p_paddr-1b)(%bx)
506
-
507
-	/* Calculate new %esp */
508
-	xorl	%eax, %eax
509
-	push	%ss
510
-	popw	%ax
511
-	shll	$4, %eax
512
-	movzwl	%sp, %ebp
513
-	addl	%eax, %ebp		/* %ebp = new %esp */
514
-	
515
-	/* Load GDT */
516
-	DATA32 lgdt %ds:(r2p_gdt-1b)(%bx)	/* Load GDT */
517
-
518
-	/* Switch to protected mode */
519
-	movl	%cr0, %eax
520
-	orb	$CR0_PE, %al
521
-	movl	%eax, %cr0
522
-
523
-	/* flush prefetch queue, and reload %cs:%eip */
524
-	DATA32 ljmp %ds:(r2p_paddr-1b)(%bx)
525
-	.code32
526
-2:
527
-	
528
-	/* Load segment registers, adjust %esp */
529
-	movw	$(r2p_pmds-r2p_gdt), %ax
530
-	movw	%ax, %ss
531
-	movl	%ebp, %esp
532
-	movw	%ax, %ds
533
-	movw	%ax, %es
534
-	movw	%ax, %fs
535
-	movw	%ax, %gs
536
-
537
-	/* Restore registers */
538
-	popl	%eax
539
-	popl	%ebx
540
-	popl	%ebp
541
-
542
-	/* return to caller */
543
-	ret
544
-
545
-r2p_gdt:
546
-	.word	r2p_gdt_end - r2p_gdt - 1	/* limit */
547
-	.long 0					/* addr */
548
-	.word 0
549
-r2p_pmcs:
550
-	/* 32 bit protected mode code segment, physical addresses */
551
-	.word	0xffff, 0
552
-	.byte	0, 0x9f, 0xcf, 0
553
-r2p_pmds:
554
-	/* 32 bit protected mode data segment, physical addresses */
555
-	.word	0xffff,0
556
-	.byte	0,0x93,0xcf,0
557
-r2p_gdt_end:
558
-
559
-r2p_paddr:
560
-	.long 2b
561
-	.word r2p_pmcs - r2p_gdt, 0
562
-
563
-
564
-	/* This is the end of the trampoline suffix code.
565
-	 */
566
-r2p_params: /* Structure must match real_to_prot_params_t in realmode.h */
567
-r2p_ret_addr:		.long 0
568
-r2p_esp:		.long 0
569
-r2p_ebx:		.long 0
570
-r2p_esi:		.long 0
571
-r2p_edi:		.long 0
572
-r2p_ebp:		.long 0
573
-r2p_out_stack:		.long 0
574
-r2p_out_stack_len:	.long 0
575
-	.globl	_real_to_prot_suffix_end
576
-_real_to_prot_suffix_end:
577
-
578
-	.globl	_real_to_prot_suffix_size
579
-	.equ	_real_to_prot_suffix_size, _real_to_prot_suffix_end - _real_to_prot_suffix
580
-	.globl	real_to_prot_suffix_size
581
-real_to_prot_suffix_size:
582
-	.word	_real_to_prot_suffix_size
583
-
584
-rm_callback_interface_end:
585
-
586
-	.globl	_rm_callback_interface_size
587
-	.equ	_rm_callback_interface_size, rm_callback_interface_end - rm_callback_interface
588
-	.globl	rm_callback_interface_size
589
-rm_callback_interface_size:
590
-	.word	_rm_callback_interface_size
591
-
592
-/****************************************************************************
593
- * END OF REAL-MODE CALLBACK INTERFACE
594
- ****************************************************************************
595
- */
596
-
597
-
598 34
 #ifdef PXE_EXPORT
599 35
 /****************************************************************************
600 36
  * PXE CALLBACK INTERFACE

+ 40
- 0
src/arch/i386/core/setjmp.S View File

@@ -0,0 +1,40 @@
1
+/* setjmp and longjmp. Use of these functions is deprecated. */
2
+
3
+	.text
4
+	.arch i386
5
+	.code32
6
+	
7
+/**************************************************************************
8
+SETJMP - Save stack context for non-local goto
9
+**************************************************************************/
10
+	.globl	setjmp
11
+setjmp:
12
+	movl	4(%esp),%ecx		/* jmpbuf */
13
+	movl	0(%esp),%edx		/* return address */
14
+	movl	%edx,0(%ecx)
15
+	movl	%ebx,4(%ecx)
16
+	movl	%esp,8(%ecx)
17
+	movl	%ebp,12(%ecx)
18
+	movl	%esi,16(%ecx)
19
+	movl	%edi,20(%ecx)
20
+	movl	$0,%eax
21
+	ret
22
+
23
+/**************************************************************************
24
+LONGJMP - Non-local jump to a saved stack context
25
+**************************************************************************/
26
+	.globl	longjmp
27
+longjmp:
28
+	movl	4(%esp),%edx		/* jumpbuf */
29
+	movl	8(%esp),%eax		/* result */
30
+	movl	0(%edx),%ecx
31
+	movl	4(%edx),%ebx
32
+	movl	8(%edx),%esp
33
+	movl	12(%edx),%ebp
34
+	movl	16(%edx),%esi
35
+	movl	20(%edx),%edi
36
+	cmpl	$0,%eax
37
+	jne	1f
38
+	movl	$1,%eax
39
+1:	movl	%ecx,0(%esp)
40
+	ret

+ 158
- 0
src/arch/i386/core/setup.S View File

@@ -0,0 +1,158 @@
1
+/****************************************************************************
2
+ * This file provides the setup() and setup16() functions.  The
3
+ * purpose of these functions is to set up the internal environment so
4
+ * that C code can execute.  This includes setting up the internal
5
+ * stack and (where applicable) setting up a GDT for virtual
6
+ * addressing.
7
+ *
8
+ * These functions are designed to be called by the prefix.
9
+ *
10
+ * The same basic assembly code is used to compile both setup()
11
+ * and setup16().
12
+ ****************************************************************************
13
+ */
14
+
15
+	.text
16
+	.arch i386
17
+
18
+#ifdef CODE16
19
+/****************************************************************************
20
+ * setup16 (real-mode far call)
21
+ *
22
+ * This function can be called by a 16-bit prefix in order to set up
23
+ * the internal (either 16-bit or 32-bit) environment.
24
+ *
25
+ * Parameters: none
26
+ *
27
+ * %cs:0000, %ds:0000 and %es:0000 must point to the start of the
28
+ * (decompressed) runtime image.
29
+ *
30
+ * If KEEP_IT_REAL is defined, then %ds:0000 may instead point to the
31
+ * start of the (decompressed) data segment portion of the runtime
32
+ * image.  If %ds==%cs, then it will be assumed that the data segment
33
+ * follows immediately after the code segment.
34
+ ****************************************************************************
35
+ */
36
+
37
+#ifdef KEEP_IT_REAL
38
+
39
+#define ENTER_FROM_EXTERNAL call ext_to_kir
40
+#define RETURN_TO_EXTERNAL call kir_to_ext
41
+#define ENTRY_POINT kir_call
42
+
43
+#else /* KEEP_IT_REAL */
44
+
45
+#define ENTER_FROM_EXTERNAL \
46
+	pushw %cs ; \
47
+	call real_to_prot ; \
48
+	.code32
49
+#define RETURN_TO_EXTERNAL \
50
+	call prot_to_real ; \
51
+	.code16
52
+#define ENTRY_POINT _prot_call /* _prot_call = OFFSET ( prot_call ) in librm */
53
+
54
+#endif /* KEEP_IT_REAL */
55
+	
56
+#define ENTRY_POINT_REGISTER di
57
+	 
58
+	.section ".text16"
59
+	.code16
60
+	.globl setup16
61
+setup16:
62
+	
63
+#else /* CODE16 */
64
+
65
+/****************************************************************************
66
+ * setup (32-bit protected-mode near call)
67
+ *
68
+ * This function can be called by a 32-bit prefix in order to set up
69
+ * the internal 32-bit environment.
70
+ *
71
+ * Parameters: none
72
+ ****************************************************************************
73
+ */
74
+
75
+#define ENTER_FROM_EXTERNAL call ext_to_int
76
+#define RETURN_TO_EXTERNAL call int_to_ext
77
+#define ENTRY_POINT int_call
78
+#define ENTRY_POINT_REGISTER edi
79
+	
80
+	.section ".text"
81
+	.code32
82
+	.globl setup
83
+setup:
84
+	
85
+#endif /* CODE16 */
86
+	
87
+	/* Preserve flags (including interrupt status) */
88
+	pushfl
89
+
90
+	/* Switch to (uninitialised) internal environment.  This will
91
+	 * preserve the external environment for when we call
92
+	 * RETURN_TO_EXTERNAL.
93
+	 */
94
+	ENTER_FROM_EXTERNAL
95
+	/* NOTE: We may have only four bytes of stack at this point */
96
+
97
+#if defined(CODE16) && defined(KEEP_IT_REAL)
98
+	
99
+	/* If %ds == %cs, then the data segment is located immediately
100
+	 * after the code segment.
101
+	 */
102
+	pushw	%ax
103
+	pushw	%bx
104
+	movw	%cs, %ax
105
+	movw	%ds, %bx
106
+	cmpw	%ax, %bx
107
+	jne	1f
108
+	addw	$_text_load_size_pgh, %ax
109
+	movw	%ax, %ds
110
+1:	popw	%bx
111
+	popw	%ax
112
+		
113
+	/* Switch to internal stack */
114
+	pushw	%ds
115
+	popw	%ss
116
+	movl	$_estack, %esp
117
+
118
+#else /* CODE16 && KEEP_IT_REAL */
119
+
120
+	/* Work out where we're running */
121
+	call	1f
122
+1:	popl	%ebp
123
+
124
+	/* Switch to internal pmode stack */
125
+	leal	(_estack-1b)(%ebp), %esp
126
+
127
+	/* Set up GDT for virtual addressing */
128
+	call	run_here
129
+
130
+#endif /* CODE16 && KEEP_IT_REAL */
131
+	
132
+	/* Switch back to external environment.  This will preserve
133
+	 * the internal environment ready for the next call.
134
+	 */
135
+	RETURN_TO_EXTERNAL
136
+
137
+	/* Pass pointer to entry-point function back to prefix.  %es
138
+	 * may, by now, have been destroyed, so we re-initialise it
139
+	 * from %cs.
140
+	 */
141
+	pushw	%cs
142
+	popw	%es
143
+	mov	$ENTRY_POINT, %ENTRY_POINT_REGISTER
144
+	
145
+	/* Restore flags (including interrupt status) */
146
+	popfl
147
+	
148
+	lret
149
+
150
+/****************************************************************************
151
+ * Internal stack
152
+ ****************************************************************************
153
+ */
154
+	.section ".stack"
155
+	.align 8
156
+_stack:
157
+	.space 4096
158
+_estack:

+ 0
- 285
src/arch/i386/core/start16.S View File

@@ -1,285 +0,0 @@
1
-/*****************************************************************************
2
- *
3
- * THIS FILE IS NOW OBSOLETE.
4
- *
5
- * The functions of this file are now placed in init.S.
6
- *
7
- *****************************************************************************
8
- */
9
-	
10
-#ifndef PCBIOS
11
-#error	"16bit code is only supported with the PCBIOS"
12
-#endif
13
-
14
-#define	CODE_SEG 0x08
15
-#define DATA_SEG 0x10
16
-
17
-#define EXEC_IN_SITU_MAGIC	0x45524548	/* 'HERE' */
18
-
19
-	.equ CR0_PE, 1
20
-
21
-#ifdef	GAS291
22
-#define DATA32 data32;
23
-#define ADDR32 addr32;
24
-#define	LJMPI(x)	ljmp	x
25
-#else
26
-#define DATA32 data32
27
-#define ADDR32 addr32
28
-/* newer GAS295 require #define	LJMPI(x)	ljmp	*x */
29
-#define	LJMPI(x)	ljmp	x
30
-#endif
31
-
32
-/*****************************************************************************
33
- *
34
- * start16 : move payload to desired area of memory, set up for exit
35
- *	     back to prefix, set up for 32-bit code.
36
- *
37
- * Enter (from prefix) with es:di = 0x4552:0x4548 if you want to
38
- * prevent start16 from moving the payload.  There are three
39
- * motivations for moving the payload:
40
- * 
41
- * 1. It may be in ROM, in which case we need to move it to RAM.
42
- * 2. Whatever loaded us probably didn't know about our memory usage
43
- *    beyond the end of the image file.  We should claim this memory
44
- *    before using it.
45
- *
46
- * Unless the prefix instructs us otherwise we will move the payload to:
47
- *
48
- *    An area of memory claimed from the BIOS via 40:13.
49
- *
50
- * We use the main Etherboot stack (within the image target) as our
51
- * stack; we don't rely on the prefix passing us a stack usable for
52
- * anything other than the prefix's return address.  The (first 512
53
- * bytes of the) prefix code segment is copied to a safe archive
54
- * location.
55
- *
56
- * When we return to the prefix (from start32), we copy this code back
57
- * to a new area of memory, restore the prefix's ss:sp and ljmp back
58
- * to the copy of the prefix.  The prefix will see a return from
59
- * start16 *but* may be executing at a new location.  Code following
60
- * the lcall to start16 must therefore be position-independent and
61
- * must also be within [cs:0000,cs:01ff].  We make absolutely no
62
- * guarantees about the stack contents when the prefix regains
63
- * control.
64
- * 
65
- * Trashes just about all registers, including all the segment
66
- * registers.
67
- *
68
- *****************************************************************************
69
- */
70
-
71
-	.text
72
-	.code16
73
-	.arch i386
74
-	.org 0
75
-	.globl _start16
76
-_start16:
77
-
78
-/*****************************************************************************
79
- * Work out where we are going to place our image (image = optional
80
- * decompressor + runtime).  Exit this stage with %ax containing the
81
- * runtime target address divided by 16 (i.e. a real-mode segment
82
- * address).
83
- *****************************************************************************
84
- */	
85
-	movw	%es, %ax
86
-	cmpw	$(EXEC_IN_SITU_MAGIC >> 16), %ax
87
-	jne	exec_moved
88
-	cmpw	$(EXEC_IN_SITU_MAGIC & 0xffff), %di
89
-	jne	exec_moved
90
-exec_in_situ: 
91
-	/* Prefix has warned us not to move the payload.  Simply
92
-	 * calculate where the image is going to end up, so we can
93
-	 * work out where to put our stack.
94
-	 */
95
-	movw	%cs, %ax
96
-	addw	$((payload-_start16)/16), %ax
97
-	jmp	99f
98
-exec_moved:
99
-	/* Claim an area of base memory from the BIOS and put the
100
-	 * payload there.  arch_relocated_to() will deal with freeing
101
-	 * up this memory once we've relocated to high memory.
102
-	 */
103
-	movw	$0x40, %ax
104
-	movw	%ax, %es
105
-	movw	%es:(0x13), %ax		/* FBMS in kb to %ax */
106
-	shlw	$6, %ax			/* ... in paragraphs */
107
-	subw	$__image_size_pgh, %ax	/* Subtract space for image */
108
-	shrw	$6, %ax			/* Round down to nearest kb */
109
-	movw	%ax, %es:(0x13)		/* ...and claim memory from BIOS */
110
-	shlw	$6, %ax
111
-99:
112
-	/* At this point %ax contains the segment address for the
113
-	 * start of the image (image = optional decompressor + runtime).
114
-	 */
115
-
116
-/*****************************************************************************
117
- * Set up stack in start32's stack space within the place we're going
118
- * to copy Etherboot to, reserve space for GDT, copy return address
119
- * from prefix stack, store prefix stack address
120
- *****************************************************************************
121
- */
122
-	popl	%esi			/* Return address */
123
-	mov	%ss, %bx		/* %es:di = prefix stack address   */
124
-	mov	%bx, %es		/* (*after* pop of return address) */
125
-	movw	%sp, %di
126
-	movw	$__offset_stack_pgh, %bx	/* Set up Etherboot stack */
127
-	addw	%ax, %bx
128
-	movw	%bx, %ss
129
-	movw	$__stack_size, %sp
130
-	subw	$(_gdt_end - _gdt), %sp	/* Reserve space for GDT */
131
-	movw	%sp, %bp		/* Record GDT location */	
132
-	/* Set up i386_rm_in_call_data_t structure on stack.  This is
133
-	 * the same structure as is set up by rm_in_call.
134
-	 */
135
-	pushl	$0			/* Dummy opcode */
136
-	pushl	%esi			/* Prefix return address */
137
-	pushfw				/* Flags */
138
-	pushw	%di			/* Prefix %sp */
139
-	pushw	%gs			/* Segment registers */
140
-	pushw	%fs
141
-	pushw	%es
142
-	pushw	%ds
143
-	pushw	%es			/* Prefix %ss */
144
-	pushw	%cs
145
-	/* Stack is now 32-bit aligned */
146
-	
147
-	/* %ax still contains image target segment address */
148
-
149
-/*****************************************************************************
150
- * Calculate image target and prefix code physical addresses, store on stack
151
- * for use in copy routine.
152
- *****************************************************************************
153
- */
154
-	movzwl	%es:-2(%di), %ebx	/* Prefix code segment */
155
-	shll	$4, %ebx
156
-	pushl	%ebx			/* Prefix code physical address */
157
-	movzwl	%ax, %edi		/* Image target segment */
158
-	shll	$4, %edi
159
-	pushl	%edi			/* Image target physical address */
160
-
161
-/*****************************************************************************
162
- * Transition to 32-bit protected mode.  Set up all segment
163
- * descriptors to use flat physical addresses.
164
- *****************************************************************************
165
- */
166
-	/* Copy gdt to area reserved on stack
167
-	 */
168
-	push	%cs			/* GDT source location -> %ds:%si */
169
-	pop	%ds
170
-	mov	$(_gdt - _start16), %si
171
-	push	%ss			/* GDT target location -> %es:%di */
172
-	pop	%es
173
-	mov	%bp, %di
174
-	mov	$(_gdt_end - _gdt), %cx
175
-	cld
176
-	rep movsb			/* Copy GDT to stack */
177
-	movl	%ss, %eax
178
-	shll	$4, %eax
179
-	movzwl	%bp, %ebx
180
-	addl	%eax, %ebx		/* Physical addr of GDT copy -> %ebx */
181
-	movl	%ebx, 2(%bp)		/* Fill in addr field in GDT */
182
-		
183
-	/* Compute the offset I am running at.
184
-	 */
185
-	movl	%cs, %ebx 
186
-	shll	$4, %ebx		/* %ebx = offset for start16 symbols */
187
-
188
-	/* Switch to 32bit protected mode.
189
-	 */
190
-	cli				/* Disable interrupts */
191
-	lgdt	(%bp)			/* Load GDT from stack */
192
-	movl	%cr0, %eax		/* Set protected mode bit */
193
-	orb	$CR0_PE, %al
194
-	movl	%eax, %cr0
195
-	movl	%ss, %eax		/* Convert stack pointer to 32bit */
196
-	shll	$4, %eax
197
-	movzwl	%sp, %esp
198
-	addl	%eax, %esp
199
-	movl	$DATA_SEG, %eax		/* Reload the segment registers */
200
-	movl	%eax, %ds
201
-	movl	%eax, %es
202
-	movl	%eax, %ss
203
-	movl	%eax, %fs
204
-	movl	%eax, %gs
205
-	/* Flush prefetch queue, and reload %cs:%eip by effectively ljmping
206
-	 * to code32_start.  Do the jump via pushl and lret because the text
207
-	 * may not be writable/
208
-	 */
209
-	pushl	$CODE_SEG
210
-	ADDR32 leal (code32_start-_start16)(%ebx), %eax
211
-	pushl	%eax	
212
-	DATA32 lret /* DATA32 needed, because we're still in 16-bit mode */
213
-
214
-_gdt:
215
-gdtarg:
216
-	.word	_gdt_end - _gdt - 1	/* limit */
217
-	.long 0				/* addr */
218
-	.word 0
219
-_pmcs:
220
-	/* 32 bit protected mode code segment */
221
-	.word	0xffff, 0
222
-	.byte	0, 0x9f, 0xcf, 0
223
-_pmds:
224
-	/* 32 bit protected mode data segment */
225
-	.word	0xffff,0
226
-	.byte	0,0x93,0xcf,0
227
-_gdt_end:
228
-
229
-	.code32
230
-code32_start:	
231
-	
232
-/*****************************************************************************
233
- * Copy payload to target location.  Do the copy backwards, since if
234
- * there's overlap with a forward copy then it means start16 is going
235
- * to get trashed during the copy anyway...
236
- *****************************************************************************
237
- */
238
-	popl	%edi		/* Image target physical address */
239
-	pushl	%edi
240
-	leal	(payload-_start16)(%ebx), %esi /* Image source physical addr */
241
-	movl	$__payload_size, %ecx /* Payload size (not image size) */
242
-	addl	%ecx, %edi	/* Start at last byte (length - 1) */
243
-	decl	%edi
244
-	addl	%ecx, %esi
245
-	decl	%esi
246
-	std			/* Backward copy of image */
247
-	rep movsb
248
-	cld
249
-	popl	%edi		/* Restore image target physical address */
250
-	leal	__decompressor_uncompressed(%edi), %ebx
251
-	subl	$_text, %ebx /* %ebx = offset for runtime symbols */
252
-
253
-/*****************************************************************************
254
- * Copy prefix to storage area within Etherboot image.
255
- *****************************************************************************
256
- */
257
-	popl	%esi		/* Prefix source physical address */
258
-	pushl	%edi
259
-	leal	_prefix_copy(%ebx), %edi /* Prefix copy phys. addr. */
260
-	leal	_eprefix_copy(%ebx), %ecx
261
-	subl	%edi, %ecx	/* Prefix copy size */
262
-	rep movsb		/* Forward copy of prefix */
263
-	popl	%edi		/* Restore image target physical address */
264
-
265
-/*****************************************************************************
266
- * Record base memory used by Etherboot image
267
- *****************************************************************************
268
- */
269
-	movl	%edi, _prefix_image_basemem (%ebx)
270
-
271
-/*****************************************************************************
272
- * Jump to start of the image (i.e. the decompressor, or start32 if
273
- * non-compressed).
274
- *****************************************************************************
275
- */
276
-	pushl	$0		/* Inform start32 that exit path is 16-bit */
277
-	jmpl	*%edi		/* Jump to image */
278
-	
279
-	.balign 16
280
-	/* Etherboot needs to be 16byte aligned or data that
281
-	 * is virtually aligned is no longer physically aligned
282
-	 * which is just nasty in general.  16byte alignment 
283
-	 * should be sufficient though.
284
-	 */
285
-payload:

+ 3
- 450
src/arch/i386/core/start32.S View File

@@ -1,18 +1,5 @@
1
-/* #defines because ljmp wants a number, probably gas bug */
2
-/*	.equ	KERN_CODE_SEG,_pmcs-_gdt	*/
3
-#define	KERN_CODE_SEG	0x08
4
-	.equ	KERN_DATA_SEG,_pmds-_gdt
5
-/*	.equ	REAL_CODE_SEG,_rmcs-_gdt	*/
6
-#define	REAL_CODE_SEG	0x18
7
-	.equ	REAL_DATA_SEG,_rmds-_gdt
8
-	.equ	FLAT_CODE_SEG,_pmcs2-_gdt
9
-	.equ	FLAT_DATA_SEG,_pmds2-_gdt
10
-	.equ	CR0_PE,1
11
-#ifdef CONFIG_X86_64
12
-	.equ	LM_CODE_SEG,  _lmcs-_gdt
13
-	.equ	LM_DATA_SEG,  _lmds-_gdt
14
-#endif
15
-
1
+#include "virtaddr.h"
2
+	
16 3
 	.equ	MSR_K6_EFER,   0xC0000080
17 4
 	.equ	EFER_LME,      0x00000100
18 5
 	.equ	X86_CR4_PAE,   0x00000020
@@ -29,12 +16,6 @@
29 16
 #define	LJMPI(x)	ljmp	x
30 17
 #endif
31 18
 
32
-#define BOCHSBP xchgw %bx, %bx
33
-
34
-#include "callbacks.h"
35
-#define NUM_PUSHA_REGS (8)
36
-#define NUM_SEG_REGS (6)
37
-	
38 19
 /*
39 20
  * NOTE: if you write a subroutine that is called from C code (gcc/egcs),
40 21
  * then you only have to take care of %ebx, %esi, %edi and %ebp.  These
@@ -54,226 +35,10 @@
54 35
  * deal correctly with 16 bit return addresses.  I tried it, but failed.
55 36
  */
56 37
 
57
-/**************************************************************************
58
- * START
59
- *
60
- * This file is no longer enterered from the top.  init.S will jump to
61
- * either _in_call or _rm_in_call, depending on the processor mode
62
- * when init.S was entered.
63
- **************************************************************************/
64 38
 	.text
65 39
 	.arch i386
66 40
 	.code32
67 41
 	
68
-/**************************************************************************
69
-_IN_CALL - make a call in to Etherboot.
70
-**************************************************************************/
71
-
72
-/* There are two 32-bit entry points: _in_call and _in_call_far, for
73
- * near calls and far calls respectively.  Both should be called with
74
- * flat physical addresses.  They will result in a call to the C
75
- * routine in_call(); see there for API details.
76
- *
77
- * Note that this routine makes fairly heavy use of the stack and no
78
- * use of fixed data areas.  This is because it must be re-entrant;
79
- * there may be more than one concurrent call in to Etherboot.
80
- */
81
-
82
-#define IC_OFFSET_VA_LIST_PTR ( 0 )
83
-#define IC_OFFSET_VA_LIST_PTR_E ( IC_OFFSET_VA_LIST_PTR + 4 )
84
-#define IC_OFFSET_REGISTERS ( IC_OFFSET_VA_LIST_PTR_E )
85
-#define IC_OFFSET_REGISTERS_E ( IC_OFFSET_REGISTERS + ( NUM_PUSHA_REGS * 4 ) )
86
-#define IC_OFFSET_SEG_REGS ( IC_OFFSET_REGISTERS_E )
87
-#define IC_OFFSET_SEG_REGS_E ( IC_OFFSET_SEG_REGS + ( NUM_SEG_REGS * 2 ) )
88
-#define IC_OFFSET_GDT ( IC_OFFSET_SEG_REGS_E )
89
-#define IC_OFFSET_GDT_E ( IC_OFFSET_GDT + 8 )
90
-#define IC_OFFSET_FLAGS ( IC_OFFSET_GDT_E )
91
-#define IC_OFFSET_FLAGS_E ( IC_OFFSET_FLAGS + 4 )
92
-#define IC_OFFSET_RETADDR ( IC_OFFSET_FLAGS_E )
93
-#define IC_OFFSET_RETADDR_E ( IC_OFFSET_RETADDR + 8 )
94
-#define IC_OFFSET_ORIG_STACK ( IC_OFFSET_RETADDR )
95
-#define IC_OFFSET_OPCODE ( IC_OFFSET_ORIG_STACK + 8 )
96
-#define IC_OFFSET_OPCODE_E ( IC_OFFSET_OPCODE + 4 )
97
-#define IC_OFFSET_VA_LIST ( IC_OFFSET_OPCODE_E )
98
-	
99
-	.code32
100
-	.globl _in_call
101
-	.globl _in_call_far
102
-_in_call:
103
-	/* Expand to far return address */
104
-	pushl	%eax			/* Store %eax */
105
-	xorl	%eax, %eax
106
-	movw	%cs, %ax
107
-	xchgl	%eax, 4(%esp)		/* 4(%esp) = %cs, %eax = ret addr */
108
-	xchgl	%eax, 0(%esp)		/* 0(%esp) = ret addr, restore %eax */
109
-_in_call_far:
110
-	/* Store flags */
111
-	pushfl
112
-	/* Store the GDT */
113
-	subl	$8, %esp
114
-	sgdt	0(%esp)
115
-	/* Store segment register values */
116
-	pushw	%gs
117
-	pushw	%fs
118
-	pushw	%es
119
-	pushw	%ds
120
-	pushw	%ss
121
-	pushw	%cs
122
-	/* Store general-purpose register values */
123
-	pushal
124
-	/* Replace %esp in store with physical %esp value on entry */
125
-	leal	(IC_OFFSET_ORIG_STACK - IC_OFFSET_REGISTERS)(%esp), %eax
126
-	movl	%eax, (IC_OFFSET_REGISTERS - IC_OFFSET_REGISTERS + 12)(%esp)
127
-	/* Store va_list pointer (physical address) */
128
-	leal	(IC_OFFSET_VA_LIST - IC_OFFSET_VA_LIST_PTR_E)(%esp), %eax
129
-	pushl	%eax
130
-	/* IC_OFFSET_*(%esp) are now valid */
131
-
132
-	/* Switch to virtual addresses */
133
-	call	_phys_to_virt
134
-
135
-	/* Fixup the va_list pointer */
136
-	movl	virt_offset, %ebp
137
-	subl	%ebp, IC_OFFSET_VA_LIST_PTR(%esp)
138
-
139
-	/* Check opcode for EB_USE_INTERNAL_STACK flag */
140
-	movl	IC_OFFSET_OPCODE(%esp), %eax
141
-	testl	$EB_USE_INTERNAL_STACK, %eax
142
-	je	2f
143
-	/* Use internal stack flag set */
144
-	/* Check %esp is not already in internal stack range */
145
-	leal	_stack, %esi		/* %esi = bottom of internal stack */
146
-	leal	_estack, %edi		/* %edi = top of internal stack */
147
-	cmpl	%esi, %esp
148
-	jb	1f
149
-	cmpl	%edi, %esp
150
-	jbe	2f
151
-1:	/* %esp not currently in internal stack range */
152
-	movl	%esp, %esi		/* %esi = original stack */
153
-	movl	$IC_OFFSET_OPCODE_E, %ecx /* %ecx = length to transfer */
154
-	subl	%ecx, %edi		/* %edi = internal stack pos */
155
-	movl	%edi, %esp		/*  = new %esp */
156
-	rep movsb			/* Copy data to internal stack */
157
-2:
158
-
159
-	/* Call to C code */
160
-	call	i386_in_call
161
-
162
-	/* Set %eax (return code from C) in registers structure on
163
-	 * stack, so that we return it to the caller.
164
-	 */
165
-	movl	%eax, (IC_OFFSET_REGISTERS + 28)(%esp)
166
-
167
-	/* Calculate physical continuation address */
168
-	movl	virt_offset, %ebp
169
-	movzwl	(IC_OFFSET_SEG_REGS + 0)(%esp), %eax	/* %cs */
170
-	movzwl	(IC_OFFSET_SEG_REGS + 2)(%esp), %ebx	/* %ss */
171
-	pushl	%eax			/* Continuation segment */
172
-	leal	1f(%ebp), %eax
173
-	pushl	%eax			/* Continuation offset */
174
-	
175
-	/* Restore caller's GDT */
176
-	cli				/* Temporarily disable interrupts */
177
-	lgdt	(8+IC_OFFSET_GDT)(%esp)
178
-	/* Reset %ss and adjust %esp */
179
-	movw	%bx, %ss
180
-	addl	%ebp, %esp
181
-	lret				/* Reload %cs:eip, flush prefetch */
182
-1:
183
-
184
-	/* Skip va_list ptr */
185
-	popl	%eax
186
-	/* Reload general-purpose registers to be returned */
187
-	popal
188
-	/* Reload segment registers as passed in from caller */
189
-	popw	%gs
190
-	popw	%fs
191
-	popw	%es
192
-	popw	%ds
193
-	addl	$(4+8), %esp	/* Skip %cs, %ss and GDT (already reloaded) */
194
-	/* Restore flags (including revert of interrupt status) */
195
-	popfl
196
-
197
-	/* Restore physical %esp from entry.  It will only be
198
-	 * different if EB_USE_INTERNAL_STACK was specified.
199
-	 */
200
-	movl	( 12 + IC_OFFSET_REGISTERS - IC_OFFSET_RETADDR )(%esp), %esp
201
-		
202
-	/* Check for EB_SKIP_OPCODE */
203
-	pushfl
204
-	testl	$EB_SKIP_OPCODE, 12(%esp)
205
-	jnz	1f
206
-	/* Normal return */
207
-	popfl
208
-	lret
209
-1:	/* Return and skip opcode */
210
-	popfl
211
-	lret	$4
212
-	
213
-/**************************************************************************
214
-RELOCATE_TO - relocate etherboot to the specified address
215
-**************************************************************************/
216
-	.globl relocate_to
217
-relocate_to:
218
-	/* Save the callee save registers */
219
-	pushl	%ebp
220
-	pushl	%esi
221
-	pushl	%edi
222
-
223
-	/* Compute the virtual destination address */
224
-	movl	16(%esp), %edi	# dest
225
-	subl	virt_offset, %edi
226
-	
227
-
228
-	/* Compute the new value of virt_offset */
229
-	movl	16(%esp), %ebp	# virt_offset
230
-	subl	$_text, %ebp
231
-
232
-	/* Fixup the gdt */
233
-	pushl	$_pmcs
234
-	pushl	%ebp		# virt_offset
235
-	call	set_seg_base
236
-	addl	$8, %esp
237
-
238
-	/* Fixup gdtarg */
239
-	leal	_gdt(%ebp), %eax
240
-	movl	%eax, gdtarg +2
241
-
242
-	/* Fixup virt_offset */
243
-	movl	%ebp, virt_offset
244
-
245
-	/* Load the move parameters */
246
-	movl	$_text, %esi
247
-	movl	$_end, %ecx
248
-	subl	%esi, %ecx
249
-
250
-	/* Move etherboot uses %esi, %edi, %ecx */
251
-	rep 
252
-	movsb
253
-
254
-	/* Reload the gdt */
255
-	cs
256
-	lgdt	gdtarg
257
-
258
-	/* Reload %cs */
259
-	ljmp	$KERN_CODE_SEG, $1f
260
-1:
261
-	/* reload other segment registers */
262
-	movl	$KERN_DATA_SEG, %eax
263
-	movl	%eax,%ds
264
-	movl	%eax,%es
265
-	movl	%eax,%ss
266
-	movl	%eax,%fs
267
-	movl	%eax,%gs
268
-
269
-	/* Restore the callee save registers */
270
-	popl	%edi
271
-	popl	%esi
272
-	popl	%ebp
273
-
274
-	/* return */
275
-	ret
276
-
277 42
 /**************************************************************************
278 43
 XSTART32 - Transfer control to the kernel just loaded
279 44
 **************************************************************************/
@@ -301,7 +66,7 @@ xstart32:
301 66
 	pushl	%ebx
302 67
 
303 68
 	/* Store the destination address on the stack */
304
-	pushl	$FLAT_CODE_SEG
69
+	pushl	$PHYSICAL_CS
305 70
 	pushl	%ecx
306 71
 
307 72
 	/* Cache virt_offset */
@@ -536,218 +301,6 @@ end_lm:
536 301
 	.arch i386
537 302
 #endif /* CONFIG_X86_64 */
538 303
 
539
-/**************************************************************************
540
-SETJMP - Save stack context for non-local goto
541
-**************************************************************************/
542
-	.globl	setjmp
543
-setjmp:
544
-	movl	4(%esp),%ecx		/* jmpbuf */
545
-	movl	0(%esp),%edx		/* return address */
546
-	movl	%edx,0(%ecx)
547
-	movl	%ebx,4(%ecx)
548
-	movl	%esp,8(%ecx)
549
-	movl	%ebp,12(%ecx)
550
-	movl	%esi,16(%ecx)
551
-	movl	%edi,20(%ecx)
552
-	movl	$0,%eax
553
-	ret
554
-
555
-/**************************************************************************
556
-LONGJMP - Non-local jump to a saved stack context
557
-**************************************************************************/
558
-	.globl	longjmp
559
-longjmp:
560
-	movl	4(%esp),%edx		/* jumpbuf */
561
-	movl	8(%esp),%eax		/* result */
562
-	movl	0(%edx),%ecx
563
-	movl	4(%edx),%ebx
564
-	movl	8(%edx),%esp
565
-	movl	12(%edx),%ebp
566
-	movl	16(%edx),%esi
567
-	movl	20(%edx),%edi
568
-	cmpl	$0,%eax
569
-	jne	1f
570
-	movl	$1,%eax
571
-1:	movl	%ecx,0(%esp)
572
-	ret
573
-
574
-/**************************************************************************
575
-_VIRT_TO_PHYS - Transition from virtual to physical addresses
576
-		Preserves all preservable registers and flags
577
-**************************************************************************/
578
-	.globl _virt_to_phys
579
-_virt_to_phys:
580
-	pushfl
581
-	pushl	%ebp
582
-	pushl	%eax
583
-	movl	virt_offset, %ebp	/* Load virt_offset */
584
-	addl	%ebp, 12(%esp)		/* Adjust the return address */
585
-
586
-	/* reload the code segment */
587
-	pushl	$FLAT_CODE_SEG
588
-	leal	1f(%ebp), %eax
589
-	pushl	%eax
590
-	lret
591
-
592
-1:
593
-	/* reload other segment registers */
594
-	movl	$FLAT_DATA_SEG, %eax
595
-	movl	%eax, %ds
596
-	movl	%eax, %es	
597
-	movl	%eax, %ss	
598
-	addl	%ebp, %esp		/* Adjust the stack pointer */
599
-	movl	%eax, %fs	
600
-	movl	%eax, %gs
601
-
602
-	popl	%eax
603
-	popl	%ebp
604
-	popfl
605
-	ret
606
-
607
-
608
-/**************************************************************************
609
-_PHYS_TO_VIRT - Transition from using physical to virtual addresses
610
-		Preserves all preservable registers and flags
611
-**************************************************************************/
612
-	.globl _phys_to_virt
613
-_phys_to_virt:
614
-	pushfl
615
-	pushl	%ebp
616
-	pushl	%eax
617
-
618
-	call	1f
619
-1:	popl	%ebp
620
-	subl	$1b, %ebp
621
-	movl	%ebp, virt_offset(%ebp)
622
-
623
-	/* Fixup the gdt */
624
-	leal	_pmcs(%ebp), %eax
625
-	pushl	%eax
626
-	pushl	%ebp
627
-	call	set_seg_base
628
-	addl	$8, %esp
629
-
630
-	/* Fixup gdtarg */
631
-	leal	_gdt(%ebp), %eax
632
-	movl	%eax, (gdtarg+2)(%ebp)
633
-
634
-	/* Load the global descriptor table */
635
-	cli
636
-	lgdt	%cs:gdtarg(%ebp)
637
-	ljmp	$KERN_CODE_SEG, $1f
638
-1:
639
-	/* reload other segment regsters */
640
-	movl	$KERN_DATA_SEG, %eax
641
-	movl	%eax, %ds
642
-	movl	%eax, %es	
643
-	movl	%eax, %ss	
644
-	subl	%ebp, %esp	/* Adjust the stack pointer */
645
-	movl	%eax, %fs	
646
-	movl	%eax, %gs
647
-
648
-	subl	%ebp, 12(%esp)	/* Adjust the return address */
649
-	popl	%eax
650
-	popl	%ebp
651
-	popfl
652
-	ret
653
-	
654
-
655
-/**************************************************************************
656
-SET_SEG_BASE - Set the base address of a segment register
657
-**************************************************************************/
658
-	.globl set_seg_base
659
-set_seg_base:
660
-	pushl	%eax
661
-	pushl	%ebx
662
-	movl	12(%esp), %eax		/* %eax = base address */
663
-	movl	16(%esp), %ebx		/* %ebx = &code_descriptor */
664
-	movw	%ax, (0+2)(%ebx)	/* CS base bits 0-15 */
665
-	movw	%ax, (8+2)(%ebx)	/* DS base bits 0-15 */
666
-	shrl	$16, %eax
667
-	movb	%al, (0+4)(%ebx)	/* CS base bits 16-23 */
668
-	movb	%al, (8+4)(%ebx)	/* DS base bits 16-23 */
669
-	movb	%ah, (0+7)(%ebx)	/* CS base bits 24-31 */
670
-	movb	%ah, (8+7)(%ebx)	/* DS base bits 24-31 */
671
-	popl	%ebx
672
-	popl	%eax
673
-	ret
674
-	
675
-/**************************************************************************
676
-GLOBAL DESCRIPTOR TABLE
677
-**************************************************************************/
678
-	.data
679
-	.align	4
680
-
681
-	.globl	_gdt
682
-	.globl	gdtarg
683
-_gdt:
684
-gdtarg:
685
-	.word	_gdt_end - _gdt - 1	/* limit */
686
-	.long	_gdt			/* addr */
687
-	.word	0
688
-
689
-	.globl	_pmcs
690
-_pmcs:
691
-	/* 32 bit protected mode code segment */
692
-	.word	0xffff,0
693
-	.byte	0,0x9f,0xcf,0
694
-
695
-_pmds:
696
-	/* 32 bit protected mode data segment */
697
-	.word	0xffff,0
698
-	.byte	0,0x93,0xcf,0
699
-
700
-_rmcs:
701
-	/* 16 bit real mode code segment */
702
-	.word	0xffff,(0&0xffff)
703
-	.byte	(0>>16),0x9b,0x00,(0>>24)
704
-
705
-_rmds:
706
-	/* 16 bit real mode data segment */
707
-	.word	0xffff,(0&0xffff)
708
-	.byte	(0>>16),0x93,0x00,(0>>24)
709
-
710
-_pmcs2:
711
-	/* 32 bit protected mode code segment, base 0 */
712
-	.word	0xffff,0
713
-	.byte	0,0x9f,0xcf,0
714
-
715
-_pmds2:
716
-	/* 32 bit protected mode data segment, base 0 */
717
-	.word	0xffff,0
718
-	.byte	0,0x93,0xcf,0
719
-
720
-#ifdef CONFIG_X86_64
721
-_lmcs:
722
-	/* 64bit long mode code segment, base 0 */
723
-	.word	0xffff, 0
724
-	.byte	0x00, 0x9f, 0xaf , 0x00
725
-_lmds:
726
-	/* 64bit long mode data segment, base 0 */
727
-	.word	0xffff, 0
728
-	.byte	0x00, 0x93, 0xcf, 0x00
729
-#endif
730
-_gdt_end:
731
-
732
-	/* The initial register contents */
733
-	.balign 4
734
-	.globl initial_regs
735
-initial_regs:
736
-	.fill 8, 4, 0
737
-
738
-	/* The virtual address offset  */	
739
-	.globl virt_offset
740
-virt_offset:
741
-	.long  	0
742
-
743
-	.section ".stack"
744
-	.p2align 3
745
-	/* allocate a 4K stack in the stack segment */
746
-	.globl	_stack
747
-_stack:
748
-	.space 4096
749
-	.globl	_estack
750
-_estack:
751 304
 #ifdef CONFIG_X86_64
752 305
 	.section ".bss"
753 306
 	.p2align 12

+ 0
- 1
src/arch/i386/core/tagged_loader.c View File

@@ -1,5 +1,4 @@
1 1
 #include "realmode.h"
2
-#include "segoff.h"
3 2
 
4 3
 struct segheader
5 4
 {

+ 15
- 7
src/arch/i386/core/video_subr.c View File

@@ -5,10 +5,14 @@
5 5
  *
6 6
  */
7 7
 
8
-#ifdef CONSOLE_DIRECT_VGA
8
+#include "stddef.h"
9
+#include "string.h"
10
+#include "io.h"
11
+#include "console.h"
12
+#include "init.h"
13
+#include "vga.h"
9 14
 
10
-#include <etherboot.h>
11
-#include <vga.h>
15
+static struct console_driver vga_console;
12 16
 
13 17
 static char *vidmem;		/* The video buffer */
14 18
 static int video_line, video_col;
@@ -17,7 +21,7 @@ static int video_line, video_col;
17 21
 
18 22
 static void memsetw(void *s, int c, unsigned int n)
19 23
 {
20
-	int i;
24
+	unsigned int i;
21 25
 	u16 *ss = (u16 *) s;
22 26
 
23 27
 	for (i = 0; i < n; i++) {
@@ -25,7 +29,7 @@ static void memsetw(void *s, int c, unsigned int n)
25 29
 	}
26 30
 }
27 31
 
28
-void video_init(void)
32
+static void video_init(void)
29 33
 {
30 34
 	static int inited=0;
31 35
 
@@ -50,7 +54,7 @@ static void video_scroll(void)
50 54
 		vidmem[i] = ' ';
51 55
 }
52 56
 
53
-void vga_putc(unsigned char byte)
57
+static void vga_putc(int byte)
54 58
 {
55 59
 	if (byte == '\n') {
56 60
 		video_line++;
@@ -90,5 +94,9 @@ void vga_putc(unsigned char byte)
90 94
 	write_crtc((video_col + (video_line *COLS)) & 0x0ff, CRTC_CURSOR_LO);
91 95
 }
92 96
 
93
-#endif
97
+static struct console_driver vga_console __console_driver = {
98
+	.putchar = vga_putc,
99
+	.disabled = 1,
100
+};
94 101
 
102
+INIT_FN ( INIT_CONSOLE, video_init, NULL, NULL );

+ 317
- 0
src/arch/i386/core/virtaddr.S View File

@@ -0,0 +1,317 @@
1
+/*
2
+ * Functions to support the virtual addressing method of relocation
3
+ * that Etherboot uses.
4
+ *
5
+ */
6
+
7
+#include "virtaddr.h"
8
+		
9
+	.arch i386
10
+
11
+/****************************************************************************
12
+ * GDT for initial transition to protected mode
13
+ *
14
+ * The segment values, PHYSICAL_CS et al, are defined in an external
15
+ * header file virtaddr.h, since they need to be shared with librm.
16
+ ****************************************************************************
17
+ */
18
+	.data
19
+	.align 16
20
+
21
+gdt:
22
+gdt_limit:		.word gdt_length - 1
23
+gdt_addr:		.long 0
24
+			.word 0 /* padding */
25
+	
26
+	.org	gdt + PHYSICAL_CS
27
+physical_cs:
28
+	/* 32 bit protected mode code segment, physical addresses */
29
+	.word	0xffff,0
30
+	.byte	0,0x9f,0xcf,0
31
+	
32
+	.org	gdt + PHYSICAL_DS
33
+physical_ds:
34
+	/* 32 bit protected mode data segment, physical addresses */
35
+	.word	0xffff,0
36
+	.byte	0,0x93,0xcf,0
37
+	
38
+	.org	gdt + VIRTUAL_CS
39
+virtual_cs:
40
+	/* 32 bit protected mode code segment, virtual addresses */
41
+	.word	0xffff,0
42
+	.byte	0,0x9f,0xcf,0
43
+
44
+	.org	gdt + VIRTUAL_DS
45
+virtual_ds:	
46
+	/* 32 bit protected mode data segment, virtual addresses */
47
+	.word	0xffff,0
48
+	.byte	0,0x93,0xcf,0
49
+
50
+#ifdef CONFIG_X86_64
51
+	
52
+	.org	gdt + LONG_CS
53
+long_cs:
54
+	/* 64bit long mode code segment, base 0 */
55
+	.word	0xffff, 0
56
+	.byte	0x00, 0x9f, 0xaf , 0x00
57
+
58
+	.org	gdt + LONG_DS
59
+long_ds:
60
+	/* 64bit long mode data segment, base 0 */
61
+	.word	0xffff, 0
62
+	.byte	0x00, 0x93, 0xcf, 0x00
63
+	
64
+#endif /* CONFIG_X86_64 */
65
+	
66
+gdt_end:		
67
+	.equ	gdt_length, gdt_end - gdt
68
+
69
+	/* The virtual address offset  */	
70
+	.globl virt_offset
71
+virt_offset:	.long  	0
72
+		
73
+	.text
74
+	.code32
75
+	
76
+/****************************************************************************
77
+ * run_here (flat physical addressing, position-independent)
78
+ *
79
+ * Set up a GDT to run Etherboot at the current location with virtual
80
+ * addressing.  This call does not switch to virtual addresses or move
81
+ * the stack pointer.  The GDT will be located within the copy of
82
+ * Etherboot.  All registers are preserved.
83
+ *
84
+ * This gets called at startup and at any subsequent relocation of
85
+ * Etherboot.
86
+ *
87
+ * Parameters: none
88
+ ****************************************************************************
89
+ */
90
+	.globl	run_here
91
+run_here:
92
+	/* Preserve registers */
93
+	pushl	%eax
94
+	pushl	%ebp
95
+
96
+	/* Find out where we're running */
97
+	call	1f
98
+1:	popl	%ebp
99
+	subl	$1b, %ebp
100
+
101
+	/* Store as virt_offset */
102
+	movl	%ebp, virt_offset(%ebp)
103
+
104
+	/* Set segment base addresses in GDT */
105
+	leal	virtual_cs(%ebp), %eax
106
+	pushl	%eax
107
+	pushl	%ebp
108
+	call	set_seg_base
109
+	popl	%eax /* discard */
110
+	popl	%eax /* discard */
111
+
112
+	/* Set physical location of GDT */
113
+	leal	gdt(%ebp), %eax
114
+	movl	%eax, gdt_addr(%ebp)
115
+
116
+	/* Load the new GDT */
117
+	lgdt	gdt(%ebp)
118
+
119
+	/* Reload new flat physical segment registers */
120
+	movl	$PHYSICAL_DS, %eax
121
+	movl	%eax, %ds
122
+	movl	%eax, %es
123
+	movl	%eax, %fs
124
+	movl	%eax, %gs
125
+	movl	%eax, %ss
126
+
127
+	/* Restore registers, convert return address to far return
128
+	 * address.
129
+	 */
130
+	popl	%ebp
131
+	movl	$PHYSICAL_CS, %eax
132
+	xchgl	%eax, 4(%esp)	/* cs now on stack, ret offset now in eax */
133
+	xchgl	%eax, 0(%esp)	/* ret offset now on stack, eax restored */
134
+	
135
+	/* Return to caller, reloading %cs with new value */
136
+	lret
137
+
138
+/****************************************************************************
139
+ * set_seg_base (any addressing, position-independent)
140
+ *
141
+ * Set the base address of a pair of segments in the GDT.  This relies
142
+ * on the layout of the GDT being (CS,DS) pairs.
143
+ *
144
+ * Parameters:
145
+ *   uint32_t base_address
146
+ *   struct gdt_entry * code_segment
147
+ * Returns:
148
+ *   none
149
+ ****************************************************************************
150
+ */
151
+	.globl set_seg_base
152
+set_seg_base:
153
+	pushl	%eax
154
+	pushl	%ebx
155
+	movl	12(%esp), %eax		/* %eax = base address */
156
+	movl	16(%esp), %ebx		/* %ebx = &code_descriptor */
157
+	movw	%ax, (0+2)(%ebx)	/* CS base bits 0-15 */
158
+	movw	%ax, (8+2)(%ebx)	/* DS base bits 0-15 */
159
+	shrl	$16, %eax
160
+	movb	%al, (0+4)(%ebx)	/* CS base bits 16-23 */
161
+	movb	%al, (8+4)(%ebx)	/* DS base bits 16-23 */
162
+	movb	%ah, (0+7)(%ebx)	/* CS base bits 24-31 */
163
+	movb	%ah, (8+7)(%ebx)	/* DS base bits 24-31 */
164
+	popl	%ebx
165
+	popl	%eax
166
+	ret
167
+	
168
+/****************************************************************************
169
+ * _virt_to_phys (virtual addressing)
170
+ *
171
+ * Switch from virtual to flat physical addresses.  %esp is adjusted
172
+ * to a physical value.  Segment registers are set to flat physical
173
+ * selectors.  All other registers are preserved.  Flags are
174
+ * preserved.
175
+ *
176
+ * Parameters: none
177
+ * Returns: none
178
+ ****************************************************************************
179
+ */
180
+	.globl _virt_to_phys
181
+_virt_to_phys:
182
+	/* Preserve registers and flags */
183
+	pushfl
184
+	pushl	%eax
185
+	pushl	%ebp
186
+
187
+	/* Change return address to a physical address */
188
+	movl	virt_offset, %ebp
189
+	addl	%ebp, 12(%esp)
190
+
191
+	/* Switch to physical code segment */
192
+	pushl	$PHYSICAL_CS
193
+	leal	1f(%ebp), %eax
194
+	pushl	%eax
195
+	lret
196
+1:
197
+	/* Reload other segment registers and adjust %esp */
198
+	movl	$PHYSICAL_DS, %eax
199
+	movl	%eax, %ds
200
+	movl	%eax, %es	
201
+	movl	%eax, %fs	
202
+	movl	%eax, %gs
203
+	movl	%eax, %ss	
204
+	addl	%ebp, %esp
205
+
206
+	/* Restore registers and flags, and return */
207
+	popl	%ebp
208
+	popl	%eax
209
+	popfl
210
+	ret
211
+
212
+/****************************************************************************
213
+ * _phys_to_virt (flat physical addressing)
214
+ *
215
+ * Switch from flat physical to virtual addresses.  %esp is adjusted
216
+ * to a virtual value.  Segment registers are set to virtual
217
+ * selectors.  All other registers are preserved.  Flags are
218
+ * preserved.
219
+ *
220
+ * Note that this depends on the GDT already being correctly set up
221
+ * (e.g. by a call to run_here()).
222
+ *
223
+ * Parameters: none
224
+ * Returns: none
225
+ ****************************************************************************
226
+ */
227
+	.globl _phys_to_virt
228
+_phys_to_virt:
229
+	/* Preserve registers and flags */
230
+	pushfl
231
+	pushl	%eax
232
+	pushl	%ebp
233
+
234
+	/* Switch to virtual code segment */
235
+	ljmp	$VIRTUAL_CS, $1f
236
+1:	
237
+	/* Reload data segment registers */
238
+	movl	$VIRTUAL_DS, %eax
239
+	movl	%eax, %ds
240
+	movl	%eax, %es	
241
+	movl	%eax, %fs	
242
+	movl	%eax, %gs
243
+
244
+	/* Reload stack segment and adjust %esp */
245
+	movl	virt_offset, %ebp
246
+	movl	%eax, %ss	
247
+	subl	%ebp, %esp
248
+
249
+	/* Change the return address to a virtual address */
250
+	subl	%ebp, 12(%esp)
251
+
252
+	/* Restore registers and flags, and return */
253
+	popl	%ebp
254
+	popl	%eax
255
+	popfl
256
+	ret
257
+
258
+/****************************************************************************
259
+ * relocate_to (virtual addressing)
260
+ *
261
+ * Relocate Etherboot to the specified address.  The runtime image
262
+ * (excluding the prefix, decompressor and compressed image) is copied
263
+ * to a new location, and execution continues in the new copy.  This
264
+ * routine is designed to be called from C code.
265
+ *
266
+ * Parameters:
267
+ *	uint32_t new_phys_addr
268
+ ****************************************************************************
269
+ */
270
+	.globl relocate_to
271
+relocate_to:
272
+	/* Save the callee save registers */
273
+	pushl	%ebp
274
+	pushl	%esi
275
+	pushl	%edi
276
+
277
+	/* Compute the physical source address and data length */
278
+	movl	$_text, %esi
279
+	movl	$_end, %ecx
280
+	subl	%esi, %ecx
281
+	addl	virt_offset, %esi
282
+
283
+	/* Compute the physical destination address */
284
+	movl	16(%esp), %edi
285
+
286
+	/* Switch to flat physical addressing */
287
+	call	_virt_to_phys
288
+	
289
+	/* Do the copy */
290
+	cld
291
+	rep movsb
292
+
293
+	/* Calculate offset to new image */
294
+	subl	%esi, %edi
295
+
296
+	/* Switch to executing in new image */
297
+	call	1f
298
+1:	popl	%ebp
299
+	leal	(2f-1b)(%ebp,%edi), %eax
300
+	jmpl	*%eax
301
+2:
302
+	/* Switch to stack in new image */
303
+	addl	%edi, %esp
304
+	
305
+	/* Call run_here() to set up GDT */
306
+	call	run_here
307
+
308
+	/* Switch to virtual addressing */
309
+	call	_phys_to_virt
310
+	
311
+	/* Restore the callee save registers */
312
+	popl	%edi
313
+	popl	%esi
314
+	popl	%ebp
315
+
316
+	/* return */
317
+	ret

+ 1
- 1
src/arch/i386/drivers/net/undi.c View File

@@ -1436,7 +1436,7 @@ static int undi_isa_probe ( struct dev *dev,
1436 1436
  * this list.
1437 1437
  */
1438 1438
 static struct pci_id undi_nics[] = {
1439
-	/* PCI_ROM(0x0000, 0x0000, "undi", "UNDI adaptor"), */
1439
+	PCI_ROM(0x0000, 0x0000, "undi", "UNDI driver support"),
1440 1440
 };
1441 1441
 
1442 1442
 static struct pci_driver undi_driver __pci_driver = {

+ 73
- 105
src/arch/i386/firmware/pcbios/bios.c View File

@@ -3,11 +3,11 @@
3 3
  * Body of routines taken from old pcbios.S
4 4
  */
5 5
 
6
-#ifdef PCBIOS
7
-
8
-#include "etherboot.h"
6
+#include "stdint.h"
9 7
 #include "realmode.h"
10
-#include "segoff.h"
8
+#include "compiler.h"
9
+
10
+#define BIOS_DATA_SEG 0x0040
11 11
 
12 12
 #define CF ( 1 << 0 )
13 13
 
@@ -23,133 +23,101 @@ timeofday BIOS interrupt.
23 23
 #define CONFIG_BIOS_CURRTICKS 1
24 24
 #endif
25 25
 #if defined(CONFIG_BIOS_CURRTICKS)
26
-unsigned long currticks (void) 
27
-{
26
+unsigned long currticks ( void ) {
28 27
 	static uint32_t days = 0;
29
-	uint32_t *ticks = VIRTUAL(0x0040,0x006c);
30
-	uint8_t *midnight = VIRTUAL(0x0040,0x0070);
28
+	uint32_t ticks;
29
+	uint8_t midnight;
31 30
 
32 31
 	/* Re-enable interrupts so that the timer interrupt can occur
33 32
 	 */
34
-	RM_FRAGMENT(rm_currticks,
35
-		"sti\n\t"
36
-		"nop\n\t"
37
-		"nop\n\t"
38
-		"cli\n\t"
39
-	);	
40
-
41
-	real_call ( rm_currticks, NULL, NULL );
42
-
43
-	if ( *midnight ) {
44
-		*midnight = 0;
33
+	REAL_EXEC ( rm_currticks,
34
+		    "sti\n\t"
35
+		    "nop\n\t"
36
+		    "nop\n\t"
37
+		    "cli\n\t",
38
+		    0,
39
+		    OUT_CONSTRAINTS (),
40
+		    IN_CONSTRAINTS (),
41
+		    CLOBBER ( "eax" ) ); /* can't have an empty clobber list */
42
+
43
+	get_real ( ticks, BIOS_DATA_SEG, 0x006c );
44
+	get_real ( midnight, BIOS_DATA_SEG, 0x0070 );
45
+
46
+	if ( midnight ) {
47
+		midnight = 0;
48
+		put_real ( midnight, BIOS_DATA_SEG, 0x0070 );
45 49
 		days += 0x1800b0;
46 50
 	}
47
-	return ( days + *ticks );
51
+	return ( days + ticks );
48 52
 }
49 53
 #endif	/* CONFIG_BIOS_CURRTICKS */
50 54
 
51
-/**************************************************************************
52
-INT15 - Call Interrupt 0x15
53
-**************************************************************************/
54
-int int15 ( int ax )
55
-{
56
-	struct {
57
-		reg16_t ax;
58
-	} PACKED in_stack;
59
-	struct {
60
-		reg16_t flags;
61
-	} PACKED out_stack;
62
-	reg16_t ret_ax;
63
-
64
-	RM_FRAGMENT(rm_int15,
65
-		"sti\n\t"
66
-		"popw %ax\n\t"
67
-		"stc\n\t"
68
-		"int $0x15\n\t"
69
-		"pushf\n\t"
70
-		"cli\n\t"
71
-	);
72
-
73
-	in_stack.ax.word = ax;
74
-	ret_ax.word = real_call ( rm_int15, &in_stack, &out_stack );
75
-
76
-	/* Carry flag clear indicates function not supported */
77
-	if ( ! ( out_stack.flags.word & CF ) ) return 0;
78
-	return ret_ax.h;
79
-}
80
-
81
-#ifdef	POWERSAVE
82 55
 /**************************************************************************
83 56
 CPU_NAP - Save power by halting the CPU until the next interrupt
84 57
 **************************************************************************/
85
-void cpu_nap ( void )
86
-{
87
-	RM_FRAGMENT(rm_cpu_nap,
88
-		"sti\n\t"
89
-		"hlt\n\t"
90
-		"cli\n\t"
91
-	);	
92
-
93
-	real_call ( rm_cpu_nap, NULL, NULL );
58
+void cpu_nap ( void ) {
59
+	REAL_EXEC ( rm_cpu_nap,
60
+		    "sti\n\t"
61
+		    "hlt\n\t"
62
+		    "cli\n\t",
63
+		    0,
64
+		    OUT_CONSTRAINTS (),
65
+		    IN_CONSTRAINTS (),
66
+		    CLOBBER ( "eax" ) ); /* can't have an empty clobber list */
94 67
 }
95
-#endif	/* POWERSAVE */
96 68
 
97 69
 #if	(TRY_FLOPPY_FIRST > 0)
98 70
 /**************************************************************************
99 71
 DISK_INIT - Initialize the disk system
100 72
 **************************************************************************/
101
-void disk_init ( void )
102
-{
103
-	RM_FRAGMENT(rm_disk_init,
104
-		"sti\n\t"
105
-		"xorw %ax,%ax\n\t"
106
-		"movb $0x80,%dl\n\t"
107
-		"int $0x13\n\t"
108
-		"cli\n\t"
109
-	);
110
-	
111
-	real_call ( rm_disk_init, NULL, NULL );
73
+void disk_init ( void ) {
74
+	REAL_EXEC ( rm_disk_init,
75
+		    "sti\n\t"
76
+		    "xorw %ax,%ax\n\t"
77
+		    "movb $0x80,%dl\n\t"
78
+		    "int $0x13\n\t"
79
+		    "cli\n\t",
80
+		    0,
81
+		    OUT_CONSTRAINTS (),
82
+		    IN_CONSTRAINTS (),
83
+   		    CLOBBER ( "eax", "ebx", "ecx", "edx",
84
+			      "ebp", "esi", "edi" ) );
112 85
 }
113 86
 
114 87
 /**************************************************************************
115 88
 DISK_READ - Read a sector from disk
116 89
 **************************************************************************/
117 90
 unsigned int pcbios_disk_read ( int drive, int cylinder, int head, int sector,
118
-				char *buf ) {
119
-	struct {
120
-		reg16_t ax;
121
-		reg16_t cx;
122
-		reg16_t dx;
123
-		segoff_t buffer;
124
-	} PACKED in_stack;
125
-	struct {
126
-		reg16_t flags;
127
-	} PACKED out_stack;
128
-	reg16_t ret_ax;
91
+				char *fixme_buf ) {
92
+	uint16_t ax, flags, discard_c, discard_d;
93
+	segoff_t buf = SEGOFF ( fixme_buf );
94
+
95
+	/* FIXME: buf should be passed in as a segoff_t rather than a
96
+	 * char *
97
+	 */
129 98
 
130
-	RM_FRAGMENT(rm_pcbios_disk_read,
131
-		"sti\n\t"
132
-		"popw %ax\n\t"
133
-		"popw %cx\n\t"
134
-		"popw %dx\n\t"
135
-		"popw %bx\n\t"
136
-		"popw %es\n\t"
137
-		"int $0x13\n\t"
138
-		"pushfw\n\t"
139
-		"cli\n\t"
99
+	REAL_EXEC ( rm_pcbios_disk_read,
100
+		    "sti\n\t"
101
+		    "pushl %%ebx\n\t"	   /* Convert %ebx to %es:bx */
102
+		    "popl %%bx\n\t"
103
+		    "popl %%es\n\t"
104
+		    "movb $0x02, %%ah\n\t" /* INT 13,2 - Read disk sector */
105
+		    "movb $0x01, %%al\n\t" /* Read one sector */
106
+		    "int $0x13\n\t"
107
+		    "pushfw\n\t"
108
+		    "popw %%bx\n\t"
109
+		    "cli\n\t",
110
+		    4,
111
+		    OUT_CONSTRAINTS ( "=a" ( ax ), "=b" ( flags ),
112
+				      "=c" ( discard_c ), "=d" ( discard_d ) ),
113
+		    IN_CONSTRAINTS ( "c" ( ( ( cylinder & 0xff ) << 8 ) |
114
+					   ( ( cylinder >> 8 ) & 0x3 ) |
115
+					   sector ),
116
+				     "d" ( ( head << 8 ) | drive ),
117
+				     "b" ( buf ) ),
118
+		    CLOBBER ( "ebp", "esi", "edi" ) );
140 119
 	);
141 120
 
142
-	in_stack.ax.h = 2; /* INT 13,2 - Read disk sector */
143
-	in_stack.ax.l = 1; /* Read one sector */
144
-	in_stack.cx.h = cylinder & 0xff;
145
-	in_stack.cx.l = ( ( cylinder >> 8 ) & 0x3 ) | sector;
146
-	in_stack.dx.h = head;
147
-	in_stack.dx.l = drive;
148
-	in_stack.buffer.segment = SEGMENT ( buf );
149
-	in_stack.buffer.offset = OFFSET ( buf );
150
-	ret_ax.word = real_call ( rm_pcbios_disk_read, &in_stack, &out_stack );
151
-	return ( out_stack.flags.word & CF ) ? ret_ax.word : 0;
121
+	return ( flags & CF ) ? ax : 0;
152 122
 }
153 123
 #endif /* TRY_FLOPPY_FIRST */
154
-
155
-#endif /* PCBIOS */

+ 76
- 0
src/arch/i386/firmware/pcbios/bios_console.c View File

@@ -0,0 +1,76 @@
1
+/* Etherboot routines for PCBIOS firmware.
2
+ *
3
+ * Body of routines taken from old pcbios.S
4
+ */
5
+
6
+#include "compiler.h"
7
+#include "realmode.h"
8
+#include "console.h"
9
+
10
+#define ZF ( 1 << 6 )
11
+
12
+/**************************************************************************
13
+bios_putchar - Print a character on console
14
+**************************************************************************/
15
+static void bios_putchar ( int character ) {
16
+	REAL_EXEC ( rm_console_putc,
17
+		    "sti\n\t"
18
+		    "movb $0x0e, %%ah\n\t"
19
+		    "movl $1, %%ebx\n\t"
20
+		    "int $0x10\n\t"
21
+		    "cli\n\t",
22
+		    1,
23
+		    OUT_CONSTRAINTS ( "=a" ( character ) ),
24
+		    IN_CONSTRAINTS ( "a" ( character ) ),
25
+		    CLOBBER ( "ebx", "ecx", "edx", "ebp", "esi", "edi" ) );
26
+
27
+	/* NOTE: %eax may be clobbered, so must be specified as an output
28
+	 * parameter, even though we don't then do anything with it.
29
+	 */
30
+}
31
+
32
+/**************************************************************************
33
+bios_getchar - Get a character from console
34
+**************************************************************************/
35
+static int bios_getchar ( void ) {
36
+	uint16_t character;
37
+	
38
+	REAL_EXEC ( rm_console_getc,
39
+		    "sti\n\t"
40
+		    "xorw %%ax, %%ax\n\t"
41
+		    "int $0x16\n\t"
42
+		    "cli\n\t",
43
+		    1,
44
+		    OUT_CONSTRAINTS ( "=a" ( character ) ),
45
+		    IN_CONSTRAINTS (),
46
+		    CLOBBER ( "ebx", "ecx", "edx", "ebp", "esi", "edi" ) );
47
+	
48
+	return ( character & 0xff );
49
+}
50
+
51
+/**************************************************************************
52
+bios_iskey - Check for keyboard interrupt
53
+**************************************************************************/
54
+static int bios_iskey ( void ) {
55
+	uint16_t flags;
56
+	
57
+	REAL_EXEC ( rm_console_ischar,
58
+		    "sti\n\t"
59
+		    "movb $1, %%ah\n\t"
60
+		    "int $0x16\n\t"
61
+		    "pushfw\n\t"
62
+		    "popw %%ax\n\t"
63
+		    "cli\n\t",
64
+		    1,
65
+		    OUT_CONSTRAINTS ( "=a" ( flags ) ),
66
+		    IN_CONSTRAINTS (),
67
+		    CLOBBER ( "ebx", "ecx", "edx", "ebp", "esi", "edi" ) );
68
+	
69
+	return ( ( flags & ZF ) == 0 );
70
+}
71
+
72
+static struct console_driver bios_console __console_driver = {
73
+	.putchar = bios_putchar,
74
+	.getchar = bios_getchar,
75
+	.iskey = bios_iskey,
76
+};

+ 0
- 85
src/arch/i386/firmware/pcbios/console.c View File

@@ -1,85 +0,0 @@
1
-/* Etherboot routines for PCBIOS firmware.
2
- *
3
- * Body of routines taken from old pcbios.S
4
- */
5
-
6
-#ifdef PCBIOS
7
-
8
-#include "etherboot.h"
9
-#include "realmode.h"
10
-#include "segoff.h"
11
-
12
-#define ZF ( 1 << 6 )
13
-
14
-/**************************************************************************
15
-CONSOLE_PUTC - Print a character on console
16
-**************************************************************************/
17
-void console_putc ( int character )
18
-{
19
-	struct {
20
-		reg16_t ax;
21
-	} PACKED in_stack;
22
-
23
-	RM_FRAGMENT(rm_console_putc,
24
-		"sti\n\t"
25
-		"popw %ax\n\t"
26
-		"movb $0x0e, %ah\n\t"
27
-		"movl $1, %ebx\n\t"
28
-		"int $0x10\n\t"
29
-		"cli\n\t"
30
-	);
31
-
32
-	in_stack.ax.l = character;
33
-	real_call ( rm_console_putc, &in_stack, NULL );
34
-}
35
-
36
-/**************************************************************************
37
-CONSOLE_GETC - Get a character from console
38
-**************************************************************************/
39
-int console_getc ( void )
40
-{
41
-	RM_FRAGMENT(rm_console_getc,
42
-		"sti\n\t"
43
-		"xorw %ax, %ax\n\t"
44
-		"int $0x16\n\t"
45
-		"xorb %ah, %ah\n\t"
46
-		"cli\n\t"
47
-	);	
48
-
49
-	return real_call ( rm_console_getc, NULL, NULL );
50
-}
51
-
52
-/**************************************************************************
53
-CONSOLE_ISCHAR - Check for keyboard interrupt
54
-**************************************************************************/
55
-int console_ischar ( void )
56
-{
57
-	RM_FRAGMENT(rm_console_ischar,
58
-		"sti\n\t"
59
-		"movb $1, %ah\n\t"
60
-		"int $0x16\n\t"
61
-		"pushfw\n\t"
62
-		"popw %ax\n\t"
63
-		"cli\n\t"
64
-	);
65
-
66
-	return ( ( real_call ( rm_console_ischar, NULL, NULL ) & ZF ) == 0 );
67
-}
68
-
69
-/**************************************************************************
70
-GETSHIFT - Get keyboard shift state
71
-**************************************************************************/
72
-int getshift ( void )
73
-{
74
-	RM_FRAGMENT(rm_getshift,
75
-		"sti\n\t"
76
-		"movb $2, %ah\n\t"
77
-		"int $0x16\n\t"
78
-		"andw $0x3, %ax\n\t" 
79
-		"cli\n\t"
80
-	);
81
-
82
-	return real_call ( rm_getshift, NULL, NULL );
83
-}
84
-
85
-#endif /* PCBIOS */

+ 90
- 0
src/arch/i386/firmware/pcbios/gateA20.c View File

@@ -0,0 +1,90 @@
1
+#include "realmode.h"
2
+#include "timer.h"
3
+#include "latch.h"
4
+#include "bios.h"
5
+
6
+#define K_RDWR		0x60		/* keyboard data & cmds (read/write) */
7
+#define K_STATUS	0x64		/* keyboard status */
8
+#define K_CMD		0x64		/* keybd ctlr command (write-only) */
9
+
10
+#define K_OBUF_FUL	0x01		/* output buffer full */
11
+#define K_IBUF_FUL	0x02		/* input buffer full */
12
+
13
+#define KC_CMD_WIN	0xd0		/* read  output port */
14
+#define KC_CMD_WOUT	0xd1		/* write output port */
15
+#define KB_SET_A20	0xdf		/* enable A20,
16
+					   enable output buffer full interrupt
17
+					   enable data line
18
+					   disable clock line */
19
+#define KB_UNSET_A20	0xdd		/* enable A20,
20
+					   enable output buffer full interrupt
21
+					   enable data line
22
+					   disable clock line */
23
+
24
+enum { Disable_A20 = 0x2400, Enable_A20 = 0x2401, Query_A20_Status = 0x2402,
25
+	Query_A20_Support = 0x2403 };
26
+
27
+#define CF ( 1 << 0 )
28
+
29
+#ifndef IBM_L40
30
+static void empty_8042 ( void )
31
+{
32
+	unsigned long time;
33
+	char st;
34
+
35
+	time = currticks() + TICKS_PER_SEC;	/* max wait of 1 second */
36
+	while ((((st = inb(K_CMD)) & K_OBUF_FUL) ||
37
+	       (st & K_IBUF_FUL)) &&
38
+	       currticks() < time)
39
+		inb(K_RDWR);
40
+}
41
+#endif	/* IBM_L40 */
42
+
43
+/*
44
+ * Gate A20 for high memory
45
+ *
46
+ * Note that this function gets called as part of the return path from
47
+ * librm's real_call, which is used to make the int15 call if librm is
48
+ * being used.  To avoid an infinite recursion, we make gateA20_set
49
+ * return immediately if it is already part of the call stack.
50
+ */
51
+void gateA20_set ( void ) {
52
+	static char reentry_guard = 0;
53
+	uint16_t flags, status;
54
+
55
+	if ( reentry_guard )
56
+		return;
57
+	reentry_guard = 1;
58
+
59
+	REAL_EXEC ( rm_enableA20,
60
+		    "sti\n\t"
61
+		    "stc\n\t"
62
+		    "int $0x15\n\t"
63
+		    "pushfw\n\t"
64
+		    "popw %%bx\n\t"
65
+		    "cli\n\t",
66
+		    2,
67
+		    OUT_CONSTRAINTS ( "=a" ( status ), "=b" ( flags ) ),
68
+		    IN_CONSTRAINTS ( "a" ( Enable_A20 ) ),
69
+		    CLOBBER ( "ecx", "edx", "ebp", "esi", "edi" ) );
70
+
71
+	if ( ( flags & CF ) ||
72
+	     ( ( status >> 8 ) & 0xff ) ) {
73
+		/* INT 15 method failed, try alternatives */
74
+#ifdef	IBM_L40
75
+		outb(0x2, 0x92);
76
+#else	/* IBM_L40 */
77
+		empty_8042();
78
+		outb(KC_CMD_WOUT, K_CMD);
79
+		empty_8042();
80
+		outb(KB_SET_A20, K_RDWR);
81
+		empty_8042();
82
+#endif	/* IBM_L40 */
83
+	}
84
+	
85
+	reentry_guard = 0;
86
+}
87
+
88
+void gateA20_unset ( void ) {
89
+	/* Not currently implemented */
90
+}

+ 145
- 120
src/arch/i386/firmware/pcbios/memsizes.c View File

@@ -1,7 +1,8 @@
1
-#ifdef PCBIOS
2
-
3
-#include "etherboot.h"
1
+#include "stdint.h"
2
+#include "stddef.h"
4 3
 #include "realmode.h"
4
+#include "init.h"
5
+#include "memsizes.h"
5 6
 
6 7
 #define CF ( 1 << 0 )
7 8
 
@@ -16,109 +17,131 @@ struct meminfo meminfo;
16 17
 /**************************************************************************
17 18
 BASEMEMSIZE - Get size of the conventional (base) memory
18 19
 **************************************************************************/
19
-unsigned short basememsize ( void )
20
-{
21
-	RM_FRAGMENT(rm_basememsize,
22
-		"int $0x12\n\t"
23
-	);	
24
-	return real_call ( rm_basememsize, NULL, NULL );
20
+static unsigned short basememsize ( void ) {
21
+	uint16_t int12_basememsize, fbms_basememsize;
22
+
23
+	/* There are two methods for retrieving the base memory size:
24
+	 * INT 12 and the BIOS FBMS counter at 40:13.  We read both
25
+	 * and use the smaller value, to be paranoid.
26
+	 */
27
+
28
+	REAL_EXEC ( rm_basememsize,
29
+		    "int $0x12\n\t",
30
+		    1,
31
+		    OUT_CONSTRAINTS ( "=a" ( int12_basememsize ) ),
32
+		    IN_CONSTRAINTS (),
33
+		    CLOBBER ( "ebx", "ecx", "edx", "ebp", "esi", "edi" ) );
34
+
35
+	get_real ( fbms_basememsize, 0x40, 0x13 );
36
+
37
+	return ( int12_basememsize < fbms_basememsize ?
38
+		 int12_basememsize : fbms_basememsize );
25 39
 }
26 40
 
27 41
 /**************************************************************************
28
-MEMSIZE - Determine size of extended memory
42
+MEMSIZE - Determine size of extended memory, in kB
29 43
 **************************************************************************/
30
-unsigned int memsize ( void )
31
-{
32
-	struct {
33
-		reg16_t ax;
34
-	} PACKED in_stack;
35
-	struct {
36
-		reg16_t ax;
37
-		reg16_t bx;
38
-		reg16_t cx;
39
-		reg16_t dx;
40
-		reg16_t flags;
41
-	} PACKED out_stack;
44
+static unsigned int memsize ( void ) {
45
+	uint16_t extmem_1m_to_16m_k, extmem_16m_plus_64k;
46
+	uint16_t confmem_1m_to_16m_k, confmem_16m_plus_64k;
47
+	uint16_t flags;
42 48
 	int memsize;
43 49
 
44
-	RM_FRAGMENT(rm_memsize,
45
-	/* Some buggy BIOSes don't clear/set carry on pass/error of
50
+	/* Try INT 15,e801 first
51
+	 *
52
+	 * Some buggy BIOSes don't clear/set carry on pass/error of
46 53
 	 * e801h memory size call or merely pass cx,dx through without
47 54
 	 * changing them, so we set carry and zero cx,dx before call.
48 55
 	 */
49
-		"stc\n\t"
50
-		"xorw %cx,%cx\n\t"
51
-		"xorw %dx,%dx\n\t"
52
-		"popw %ax\n\t"
53
-		"int $0x15\n\t"
54
-		"pushfw\n\t"
55
-		"pushw %dx\n\t"
56
-		"pushw %cx\n\t"
57
-		"pushw %bx\n\t"
58
-		"pushw %ax\n\t"
59
-	);
60
-
61
-	/* Try INT 15,e801 first */
62
-	in_stack.ax.word = 0xe801;
63
-	real_call ( rm_memsize, &in_stack, &out_stack );
64
-	if ( out_stack.flags.word & CF ) {
65
-		/* INT 15,e801 not supported: try INT 15,88 */
66
-		in_stack.ax.word = 0x8800;
67
-		memsize = real_call ( rm_memsize, &in_stack, &out_stack );
68
-	} else {
69
-		/* Some BIOSes report extended memory via ax,bx rather
70
-		 * than cx,dx
71
-		 */
72
-		if ( (out_stack.cx.word==0) && (out_stack.dx.word==0) ) {
73
-			/* Use ax,bx */
74
-			memsize = ( out_stack.bx.word<<6 ) + out_stack.ax.word;
56
+	REAL_EXEC ( rm_mem_e801,
57
+		    "stc\n\t"
58
+		    "int $0x15\n\t"
59
+		    "pushfw\n\t"	/* flags -> %di */
60
+		    "popw %%di\n\t",
61
+		    5,
62
+		    OUT_CONSTRAINTS ( "=a" ( extmem_1m_to_16m_k ),
63
+				      "=b" ( extmem_16m_plus_64k ),
64
+				      "=c" ( confmem_1m_to_16m_k ),
65
+				      "=d" ( confmem_16m_plus_64k ),
66
+				      "=D" ( flags ) ),
67
+		    IN_CONSTRAINTS ( "a" ( 0xe801 ),
68
+				     "c" ( 0 ),
69
+				     "d" ( 0 ) ),
70
+		    CLOBBER ( "ebp", "esi" ) );
71
+
72
+	if ( ! ( flags & CF ) ) {
73
+		/* INT 15,e801 succeeded */
74
+		if ( confmem_1m_to_16m_k || confmem_16m_plus_64k ) {
75
+			/* Use confmem (cx,dx) values */
76
+			memsize = confmem_1m_to_16m_k +
77
+				( confmem_16m_plus_64k << 6 );
75 78
 		} else {
76
-			/* Use cx,dx */
77
-			memsize = ( out_stack.dx.word<<6 ) + out_stack.cx.word;
79
+			/* Use extmem (ax,bx) values */
80
+			memsize = extmem_1m_to_16m_k +
81
+				( extmem_16m_plus_64k << 6 );
78 82
 		}
83
+	} else {
84
+		/* INT 15,e801 failed; fall back to INT 15,88
85
+		 *
86
+		 * CF is apparently unreliable and should be ignored.
87
+		 */
88
+		REAL_EXEC ( rm_mem_88,
89
+			    "int $0x15\n\t",
90
+			    1,
91
+			    OUT_CONSTRAINTS ( "=a" ( extmem_1m_to_16m_k ) ),
92
+			    IN_CONSTRAINTS ( "a" ( 0x88 << 8 ) ),
93
+			    CLOBBER ( "ebx", "ecx", "edx",
94
+				      "ebp", "esi", "edi" ) );
95
+		memsize = extmem_1m_to_16m_k;
79 96
 	}
97
+
80 98
 	return memsize;
81 99
 }
82 100
 
83
-#define SMAP ( 0x534d4150 )
84
-int meme820 ( struct e820entry *buf, int count )
85
-{
86
-	struct {
87
-		reg16_t flags;
88
-		reg32_t eax;
89
-		reg32_t ebx;
90
-		struct e820entry entry;
91
-	} PACKED stack;
92
-	int index = 0;
93
-
94
-	RM_FRAGMENT(rm_meme820,
95
-		"addw $6, %sp\n\t"	/* skip flags, eax */
96
-		"popl %ebx\n\t"
97
-		"pushw %ss\n\t"	/* es:di = ss:sp */
98
-		"popw %es\n\t"
99
-		"movw %sp, %di\n\t"
100
-		"movl $0xe820, %eax\n\t"
101
-		"movl $" RM_STR(SMAP) ", %edx\n\t"
102
-		"movl $" RM_STR(E820ENTRY_SIZE) ", %ecx\n\t"
103
-		"int $0x15\n\t"
104
-		"pushl %ebx\n\t"
105
-		"pushl %eax\n\t"
106
-		"pushfw\n\t"
107
-	);
108
-
109
-	stack.ebx.dword = 0; /* 'EOF' marker */
110
-	while ( ( index < count ) &&
111
-		( ( index == 0 ) || ( stack.ebx.dword != 0 ) ) ) {
112
-		real_call ( rm_meme820, &stack, &stack );
113
-		if ( stack.eax.dword != SMAP ) return 0;
114
-		if ( stack.flags.word & CF ) return 0;
115
-		buf[index++] = stack.entry;
116
-	}
101
+/**************************************************************************
102
+MEME820 - Retrieve the E820 BIOS memory map
103
+**************************************************************************/
104
+#define SMAP ( 0x534d4150 ) /* "SMAP" */
105
+static int meme820 ( struct e820entry *buf, int count ) {
106
+	int index;
107
+	uint16_t basemem_entry;
108
+	uint32_t smap, next;
109
+	uint16_t flags;
110
+	uint32_t discard_c, discard_d;
111
+
112
+	index = 0;
113
+	next = 0;
114
+	do {
115
+		basemem_entry = BASEMEM_PARAMETER_INIT ( buf[index] );
116
+		REAL_EXEC ( rm_mem_e820,
117
+			    "int $0x15\n\t"
118
+			    "pushfw\n\t"	/* flags -> %di */
119
+			    "popw %%di\n\t",
120
+			    5,
121
+			    OUT_CONSTRAINTS ( "=a" ( smap ),
122
+					      "=b" ( next ),
123
+					      "=c" ( discard_c ),
124
+					      "=d" ( discard_d ),
125
+					      "=D" ( flags ) ),
126
+			    IN_CONSTRAINTS ( "a" ( 0xe820 ),
127
+					     "b" ( next ),
128
+					     "c" ( sizeof (struct e820entry) ),
129
+					     "d" ( SMAP ),
130
+					     "D" ( basemem_entry ) ),
131
+			    CLOBBER ( "ebp", "esi" ) );
132
+		BASEMEM_PARAMETER_DONE ( buf[index] );
133
+		if ( smap != SMAP ) return 0;
134
+		if ( flags & CF ) break;
135
+		index++;
136
+	} while ( ( index < count ) && ( next != 0 ) );
137
+		
117 138
 	return index;
118 139
 }
119 140
 
120
-void get_memsizes(void)
121
-{
141
+/**************************************************************************
142
+GET_MEMSIZES - Retrieve the system memory map via any available means
143
+**************************************************************************/
144
+void get_memsizes ( void ) {
122 145
 	/* Ensure we don't stomp bios data structutres.
123 146
 	 * the interrupt table: 0x000 - 0x3ff
124 147
 	 * the bios data area:  0x400 - 0x502
@@ -127,16 +150,19 @@ void get_memsizes(void)
127 150
 	static const unsigned min_addr = 0x600;
128 151
 	unsigned i;
129 152
 	unsigned basemem;
130
-	basemem = get_free_base_memory();
153
+
154
+	/* Retrieve memory information from the BIOS */
131 155
 	meminfo.basememsize = basememsize();
156
+	basemem = meminfo.basememsize << 10;
132 157
 	meminfo.memsize = memsize();
133 158
 #ifndef IGNORE_E820_MAP
134
-	meminfo.map_count = meme820(meminfo.map, E820MAX);
159
+	meminfo.map_count = meme820 ( meminfo.map, E820MAX );
135 160
 #else
136 161
 	meminfo.map_count = 0;
137 162
 #endif
138
-	if (meminfo.map_count == 0) {
139
-		/* If we don't have an e820 memory map fake it */
163
+
164
+	/* If we don't have an e820 memory map fake it */
165
+	if ( meminfo.map_count == 0 ) {
140 166
 		meminfo.map_count = 2;
141 167
 		meminfo.map[0].addr = 0;
142 168
 		meminfo.map[0].size = meminfo.basememsize << 10;
@@ -145,57 +171,56 @@ void get_memsizes(void)
145 171
 		meminfo.map[1].size = meminfo.memsize << 10;
146 172
 		meminfo.map[1].type = E820_RAM;
147 173
 	}
174
+
148 175
 	/* Scrub the e820 map */
149
-	for(i = 0; i < meminfo.map_count; i++) {
150
-		if (meminfo.map[i].type != E820_RAM) {
176
+	for ( i = 0; i < meminfo.map_count; i++ ) {
177
+		if ( meminfo.map[i].type != E820_RAM ) {
151 178
 			continue;
152 179
 		}
180
+
153 181
 		/* Reserve the bios data structures */
154
-		if (meminfo.map[i].addr < min_addr) {
182
+		if ( meminfo.map[i].addr < min_addr ) {
155 183
 			unsigned long delta;
156 184
 			delta = min_addr - meminfo.map[i].addr;
157
-			if (delta > meminfo.map[i].size) {
185
+			if ( delta > meminfo.map[i].size ) {
158 186
 				delta = meminfo.map[i].size;
159 187
 			}
160 188
 			meminfo.map[i].addr = min_addr;
161 189
 			meminfo.map[i].size -= delta;
162 190
 		}
163
-		/* Ensure the returned e820 map is in sync 
164
-		 * with the actual memory state 
191
+
192
+		/* Ensure the returned e820 map is in sync with the
193
+		 * actual memory state
165 194
 		 */
166
-		if ((meminfo.map[i].addr < 0xa0000) && 
167
-			((meminfo.map[i].addr + meminfo.map[i].size) > basemem))
168
-		{
169
-			if (meminfo.map[i].addr <= basemem) {
170
-				meminfo.map[i].size = basemem - meminfo.map[i].addr;
195
+		if ( ( meminfo.map[i].addr < 0xa0000 ) && 
196
+		     (( meminfo.map[i].addr+meminfo.map[i].size ) > basemem )){
197
+			if ( meminfo.map[i].addr <= basemem ) {
198
+				meminfo.map[i].size = basemem
199
+					- meminfo.map[i].addr;
171 200
 			} else {
172 201
 				meminfo.map[i].addr = basemem;
173 202
 				meminfo.map[i].size = 0;
174 203
 			}
175 204
 		}
176 205
 	}
206
+
177 207
 #if MEMSIZES_DEBUG
178
-{
179
-	int i;
180
-	printf("basememsize %d\n", meminfo.basememsize);
181
-	printf("memsize %d\n",     meminfo.memsize);
182
-	printf("Memory regions(%d):\n", meminfo.map_count);
183
-	for(i = 0; i < meminfo.map_count; i++) {
208
+	printf ( "basememsize %d\n", meminfo.basememsize );
209
+	printf ( "memsize %d\n",     meminfo.memsize );
210
+	printf ( "Memory regions(%d):\n", meminfo.map_count );
211
+	for ( i = 0; i < meminfo.map_count; i++ ) {
184 212
 		unsigned long long r_start, r_end;
185 213
 		r_start = meminfo.map[i].addr;
186 214
 		r_end = r_start + meminfo.map[i].size;
187
-		printf("[%X%X, %X%X) type %d\n", 
188
-			(unsigned long)(r_start >> 32),
189
-			(unsigned long)r_start,
190
-			(unsigned long)(r_end >> 32),
191
-			(unsigned long)r_end,
192
-			meminfo.map[i].type);
193
-#if defined(CONSOLE_FIRMWARE)
194
-		sleep(1); /* No way to see 32 entries on a standard 80x25 screen... */
195
-#endif
215
+		printf ( "[%X%X, %X%X) type %d\n", 
216
+			 ( unsigned long ) ( r_start >> 32 ),
217
+			 ( unsigned long ) r_start,
218
+			 ( unsigned long ) ( r_end >> 32 ),
219
+			 ( unsigned long ) r_end,
220
+			 meminfo.map[i].type );
196 221
 	}
197
-}
198 222
 #endif
223
+
199 224
 }
200 225
 
201
-#endif /* PCBIOS */
226
+INIT_FN ( INIT_MEMSIZES, get_memsizes, NULL, NULL );

+ 10
- 0
src/arch/i386/include/bios.h View File

@@ -0,0 +1,10 @@
1
+#ifndef BIOS_H
2
+#define BIOS_H
3
+
4
+extern unsigned long currticks ( void );
5
+extern void cpu_nap ( void );
6
+extern void disk_init ( void );
7
+extern unsigned int pcbios_disk_read ( int drive, int cylinder, int head,
8
+				       int sector, char *fixme_buf );
9
+
10
+#endif /* BIOS_H */

+ 27
- 0
src/arch/i386/include/bochs.h View File

@@ -0,0 +1,27 @@
1
+#ifndef BOCHS_H
2
+#define BOCHS_H
3
+
4
+/*
5
+ * This file defines "bochsbp", the magic breakpoint instruction that
6
+ * is incredibly useful when debugging under bochs.
7
+ *
8
+ */
9
+
10
+#ifdef ASSEMBLY
11
+
12
+/* Breakpoint for when debugging under bochs */
13
+#define bochsbp xchgw %bx, %bx
14
+#define BOCHSBP bochsbp
15
+
16
+#else /* ASSEMBLY */
17
+
18
+/* Breakpoint for when debugging under bochs */
19
+static inline void bochsbp ( void ) {
20
+	__asm__ __volatile__ ( "xchgw %bx, %bx" );
21
+}
22
+
23
+#endif /* ASSEMBLY */
24
+
25
+#warning "bochs.h should not be included into production code"
26
+
27
+#endif /* BOCHS_H */

+ 1
- 1
src/arch/i386/include/hidemem.h View File

@@ -1,7 +1,7 @@
1 1
 #ifndef HIDEMEM_H
2 2
 #define HIDEMEM_H
3 3
 
4
-#include "segoff.h"
4
+#include "realmode.h"
5 5
 
6 6
 extern int install_e820mangler ( void *new_mangler );
7 7
 extern int hide_etherboot ( void );

+ 12
- 7
src/arch/i386/include/hooks.h View File

@@ -1,9 +1,14 @@
1
-#ifndef ETHERBOOT_I386_HOOKS_H
2
-#define ETHERBOOT_I386_HOOKS_H
1
+#ifndef HOOKS_H
2
+#define HOOKS_H
3 3
 
4
-void arch_main(in_call_data_t *data, va_list params);
5
-void arch_on_exit(int status);
6
-#define arch_relocate_to(addr)
7
-void arch_relocated_from ( uint32_t old_addr );
4
+/* in hooks.o */
5
+extern void arch_initialise ( struct i386_all_regs *regs,
6
+			      void (*retaddr) (void) );
7
+extern void arch_main ( struct i386_all_regs *regs );
8 8
 
9
-#endif /* ETHERBOOT_I386_HOOKS_H */
9
+/* in hooks_rm.o */
10
+extern void arch_rm_initialise ( struct i386_all_regs *regs,
11
+				 void (*retaddr) (void) );
12
+extern void arch_rm_main ( struct i386_all_regs *regs );
13
+
14
+#endif /* HOOKS_H */

+ 2
- 16
src/arch/i386/include/io.h View File

@@ -1,22 +1,8 @@
1 1
 #ifndef	ETHERBOOT_IO_H
2 2
 #define ETHERBOOT_IO_H
3 3
 
4
-
5
-/* Amount of relocation etherboot is experiencing */
6
-extern unsigned long virt_offset;
7
-
8
-/* Don't require identity mapped physical memory,
9
- * osloader.c is the only valid user at the moment.
10
- */
11
-static inline unsigned long virt_to_phys(volatile const void *virt_addr)
12
-{
13
-	return ((unsigned long)virt_addr) + virt_offset;
14
-}
15
-
16
-static inline void *phys_to_virt(unsigned long phys_addr)
17
-{
18
-	return (void *)(phys_addr - virt_offset);
19
-}
4
+#include "compiler.h"
5
+#include "virtaddr.h"
20 6
 
21 7
 /* virt_to_bus converts an addresss inside of etherboot [_start, _end]
22 8
  * into a memory access cards can use.

+ 18
- 0
src/arch/i386/include/kir.h View File

@@ -0,0 +1,18 @@
1
+#ifndef KIR_H
2
+#define KIR_H
3
+
4
+#ifndef KEEP_IT_REAL
5
+#error "kir.h can be used only with -DKEEP_IT_REAL"
6
+#endif
7
+
8
+#ifdef ASSEMBLY
9
+
10
+#define code32 code16gcc
11
+
12
+#else /* ASSEMBLY */
13
+
14
+__asm__ ( ".code16gcc" );
15
+
16
+#endif /* ASSEMBLY */
17
+
18
+#endif /* KIR_H */

+ 184
- 0
src/arch/i386/include/libkir.h View File

@@ -0,0 +1,184 @@
1
+#ifndef LIBKIR_H
2
+#define LIBKIR_H
3
+
4
+#include "realmode.h"
5
+
6
+#ifndef ASSEMBLY
7
+
8
+/*
9
+ * Full API documentation for these functions is in realmode.h.
10
+ *
11
+ */
12
+
13
+/* Copy to/from base memory */
14
+
15
+static inline void copy_to_real_libkir ( uint16_t dest_seg, uint16_t dest_off,
16
+					 void *src, size_t n ) {
17
+	__asm__ ( "movw %4, %%es\n\t"
18
+		  "cld\n\t"
19
+		  "rep movsb\n\t"
20
+		  "pushw %%ds\n\t" /* restore %es */
21
+		  "popw %%es\n\t"
22
+		  : "=S" ( src ), "=D" ( dest_off ), "=c" ( n ) /* clobbered */
23
+		  : "S" ( src ), "r" ( dest_seg ), "D" ( dest_off ), "c" ( n )
24
+		  : "memory"
25
+		  );
26
+}
27
+
28
+static inline void copy_from_real_libkir ( void *dest,
29
+					   uint16_t src_seg, uint16_t src_off,
30
+					   size_t n ) {
31
+	__asm__ ( "movw %%ax, %%ds\n\t"
32
+		  "cld\n\t"
33
+		  "rep movsb\n\t"
34
+		  "pushw %%es\n\t" /* restore %ds */
35
+		  "popw %%ds\n\t"
36
+		  : "=S" ( src_off ), "=D" ( dest ), "=c" ( n ) /* clobbered */
37
+		  : "a" ( src_seg ), "S" ( src_off ), "D" ( dest ), "c" ( n )
38
+		  : "memory"
39
+		  );
40
+}
41
+#define copy_to_real copy_to_real_libkir
42
+#define copy_from_real copy_from_real_libkir
43
+
44
+/*
45
+ * Transfer individual values to/from base memory.  There may well be
46
+ * a neater way to do this.  We have two versions: one for constant
47
+ * offsets (where the mov instruction must be of the form "mov
48
+ * %es:123, %xx") and one for non-constant offsets (where the mov
49
+ * instruction must be of the form "mov %es:(%xx), %yx".  If it's
50
+ * possible to incorporate both forms into one __asm__ instruction, I
51
+ * don't know how to do it.
52
+ *
53
+ * Ideally, the mov instruction should be "mov%z0"; the "%z0" is meant
54
+ * to expand to either "b", "w" or "l" depending on the size of
55
+ * operand 0.  This would remove the (minor) ambiguity in the mov
56
+ * instruction.  However, gcc on at least my system barfs with an
57
+ * "internal compiler error" when confronted with %z0.
58
+ *
59
+ */
60
+
61
+#define put_real_kir_const_off( var, seg, off )		  		     \
62
+	__asm__ ( "movw %w1, %%es\n\t"					     \
63
+		  "mov %0, %%es:%c2\n\t"				     \
64
+		  "pushw %%ds\n\t" /* restore %es */			     \
65
+		  "popw %%es\n\t"					     \
66
+		  :							     \
67
+		  : "r,r" ( var ), "rm,rm" ( seg ), "i,!r" ( off )	     \
68
+		  )
69
+
70
+#define put_real_kir_nonconst_off( var, seg, off )	  		     \
71
+	__asm__ ( "movw %w1, %%es\n\t"					     \
72
+		  "mov %0, %%es:(%2)\n\t"				     \
73
+		  "pushw %%ds\n\t" /* restore %es */			     \
74
+		  "popw %%es\n\t"					     \
75
+		  :							     \
76
+		  : "r" ( var ), "rm" ( seg ), "r" ( off )		     \
77
+		  )
78
+
79
+#define put_real_kir( var, seg, off )					     \
80
+	do {								     \
81
+	  if ( __builtin_constant_p ( off ) )				     \
82
+		  put_real_kir_const_off ( var, seg, off );		     \
83
+	  else								     \
84
+		  put_real_kir_nonconst_off ( var, seg, off );		     \
85
+	} while ( 0 )
86
+
87
+#define get_real_kir_const_off( var, seg, off )		  		     \
88
+	__asm__ ( "movw %w1, %%es\n\t"					     \
89
+		  "mov %%es:%c2, %0\n\t"				     \
90
+		  "pushw %%ds\n\t" /* restore %es */			     \
91
+		  "popw %%es\n\t"					     \
92
+		  : "=r,r" ( var )					     \
93
+		  : "rm,rm" ( seg ), "i,!r" ( off )			     \
94
+		  )
95
+
96
+#define get_real_kir_nonconst_off( var, seg, off )			     \
97
+	__asm__ ( "movw %w1, %%es\n\t"					     \
98
+		  "mov %%es:(%2), %0\n\t"				     \
99
+		  "pushw %%ds\n\t" /* restore %es */			     \
100
+		  "popw %%es\n\t"					     \
101
+		  : "=r" ( var )					     \
102
+		  : "rm" ( seg ), "r" ( off )				     \
103
+		  )
104
+
105
+#define get_real_kir( var, seg, off )					     \
106
+	do {								     \
107
+	  if ( __builtin_constant_p ( off ) )				     \
108
+		  get_real_kir_const_off ( var, seg, off );		     \
109
+	  else								     \
110
+		  get_real_kir_nonconst_off ( var, seg, off );		     \
111
+	} while ( 0 )
112
+
113
+#define put_real put_real_kir
114
+#define get_real get_real_kir
115
+
116
+/* Place/remove parameter on real-mode stack in a way that's
117
+ * compatible with libkir
118
+ */
119
+#define BASEMEM_PARAMETER_INIT_LIBKIR( param ) \
120
+	( ( uint16_t ) ( ( uint32_t ) & ( param ) ) )
121
+#define BASEMEM_PARAMETER_DONE_LIBKIR( param )
122
+#define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBKIR
123
+#define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBKIR
124
+
125
+/* REAL_CALL: call an external real-mode routine */
126
+#define OUT_CONSTRAINTS(...) __VA_ARGS__
127
+#define IN_CONSTRAINTS(...) "m" ( __routine ), ## __VA_ARGS__
128
+#define CLOBBER(...) __VA_ARGS__
129
+#define REAL_CALL( routine, num_out_constraints, out_constraints,	     \
130
+		   in_constraints, clobber )				     \
131
+	do {								     \
132
+		segoff_t __routine = routine;				     \
133
+		__asm__ __volatile__ (					     \
134
+			"pushl %" #num_out_constraints "\n\t"		     \
135
+			".code16\n\t"					     \
136
+			"pushw %%gs\n\t"	/* preserve segs */	     \
137
+			"pushw %%fs\n\t"				     \
138
+			"pushw %%es\n\t"				     \
139
+			"pushw %%ds\n\t"				     \
140
+			"pushw %%cs\n\t"	/* lcall to routine */	     \
141
+			"call 1f\n\t"					     \
142
+			"jmp 2f\n\t"					     \
143
+			"\n1:\n\t"					     \
144
+			"addr32 pushl 12(%%esp)\n\t"			     \
145
+			"lret\n\t"					     \
146
+			"\n2:\n\t"					     \
147
+			"popw %%ds\n\t"		/* restore segs */	     \
148
+			"popw %%es\n\t"					     \
149
+			"popw %%fs\n\t"					     \
150
+			"popw %%gs\n\t"					     \
151
+			"addw $4, %%sp\n\t"				     \
152
+			".code16gcc\n\t"				     \
153
+			: out_constraints : in_constraints : clobber  	     \
154
+		);							     \
155
+	} while ( 0 )
156
+
157
+/* REAL_EXEC: execute some inline assembly code in a way that matches
158
+ * the interface of librm
159
+ */
160
+
161
+#define IN_CONSTRAINTS_NO_ROUTINE( routine, ... ) __VA_ARGS__
162
+#define REAL_EXEC( name, asm_code_str, num_out_constraints, out_constraints, \
163
+		   in_constraints, clobber )				     \
164
+	__asm__ __volatile__ (						     \
165
+		".code16\n\t"						     \
166
+		"pushw %%gs\n\t"					     \
167
+		"pushw %%fs\n\t"					     \
168
+		"pushw %%es\n\t"					     \
169
+		"pushw %%ds\n\t"					     \
170
+		"\n" #name ":\n\t"					     \
171
+		asm_code_str						     \
172
+		"popw %%ds\n\t"						     \
173
+		"popw %%es\n\t"						     \
174
+		"popw %%fs\n\t"						     \
175
+		"popw %%gs\n\t"						     \
176
+		".code16gcc\n\t"					     \
177
+		: out_constraints					     \
178
+		: IN_CONSTRAINTS_NO_ROUTINE ( in_constraints )		     \
179
+		: clobber				   		     \
180
+		);
181
+
182
+#endif /* ASSEMBLY */
183
+
184
+#endif /* LIBKIR_H */

+ 186
- 0
src/arch/i386/include/librm.h View File

@@ -0,0 +1,186 @@
1
+#ifndef LIBRM_H
2
+#define LIBRM_H
3
+
4
+/* Drag in protected-mode segment selector values */
5
+#include "virtaddr.h"
6
+#include "realmode.h"
7
+
8
+#ifndef ASSEMBLY
9
+
10
+#include "stddef.h"
11
+#include "string.h"
12
+
13
+/*
14
+ * Data structures and type definitions
15
+ *
16
+ */
17
+
18
+/* Real-mode call parameter block, as passed to real_call */
19
+struct real_call_params {
20
+	struct i386_seg_regs;
21
+	struct i386_regs;
22
+	segoff_t rm_code;
23
+	segoff_t reserved;
24
+} PACKED;
25
+
26
+/* Current location of librm in base memory */
27
+extern char *installed_librm;
28
+
29
+/* Start and size of our source copy of librm (i.e. the one that we
30
+ * can install by copying it to base memory and setting
31
+ * installed_librm)
32
+ */
33
+extern char librm[];
34
+extern size_t _librm_size[];
35
+
36
+/* Linker symbols for offsets within librm.  Other symbols should
37
+ * almost certainly not be referred to from C code.
38
+ */
39
+extern void (*_real_to_prot[]) ( void );
40
+extern void (*_prot_to_real[]) ( void );
41
+extern void (*_prot_call[]) ( void );
42
+extern void (*_real_call[]) ( void );
43
+extern segoff_t _rm_stack[];
44
+extern uint32_t _pm_stack[];
45
+extern char _librm_ref_count[];
46
+
47
+/* Symbols within current installation of librm */
48
+#define LIBRM_VAR( sym ) \
49
+	( * ( ( typeof ( * _ ## sym ) * ) \
50
+	      & ( installed_librm [ (int) _ ## sym ] ) ) )
51
+#define LIBRM_FN( sym ) \
52
+	 ( ( typeof ( * _ ## sym ) ) \
53
+	      & ( installed_librm [ (int) _ ## sym ] ) )
54
+#define LIBRM_CONSTANT( sym ) \
55
+	( ( typeof ( * _ ## sym ) ) ( _ ## sym ) )
56
+#define inst_real_to_prot	LIBRM_FN ( real_to_prot )
57
+#define inst_prot_to_real	LIBRM_FN ( prot_to_real )
58
+#define inst_prot_call		LIBRM_FN ( prot_call )
59
+#define inst_real_call		LIBRM_FN ( real_call )
60
+#define inst_rm_stack		LIBRM_VAR ( rm_stack )
61
+#define inst_pm_stack		LIBRM_VAR ( pm_stack )
62
+#define inst_librm_ref_count	LIBRM_VAR ( librm_ref_count )
63
+#define librm_size		LIBRM_CONSTANT ( librm_size )
64
+
65
+/* Functions that librm expects to be able to link to.  Included here
66
+ * so that the compiler will catch prototype mismatches.
67
+ */
68
+extern void _phys_to_virt ( void );
69
+extern void _virt_to_phys ( void );
70
+extern void gateA20_set ( void );
71
+
72
+/*
73
+ * librm_mgmt: functions for manipulating base memory and executing
74
+ * real-mode code.
75
+ *
76
+ * Full API documentation for these functions is in realmode.h.
77
+ *
78
+ */
79
+
80
+/* Macro for obtaining a physical address from a segment:offset pair. */
81
+#define VIRTUAL(x,y) ( phys_to_virt ( ( ( x ) << 4 ) + ( y ) ) )
82
+
83
+/* Copy to/from base memory */
84
+static inline void copy_to_real_librm ( uint16_t dest_seg, uint16_t dest_off,
85
+					void *src, size_t n ) {
86
+	memcpy ( VIRTUAL ( dest_seg, dest_off ), src, n );
87
+}
88
+static inline void copy_from_real_librm ( void *dest,
89
+					  uint16_t src_seg, uint16_t src_off,
90
+					  size_t n ) {
91
+	memcpy ( dest, VIRTUAL ( src_seg, src_off ), n );
92
+}
93
+#define put_real_librm( var, dest_seg, dest_off )			      \
94
+	do {								      \
95
+		* ( ( typeof(var) * ) VIRTUAL ( dest_seg, dest_off ) ) = var; \
96
+	} while ( 0 )
97
+#define get_real_librm( var, src_seg, src_off )				      \
98
+	do {								      \
99
+		var = * ( ( typeof(var) * ) VIRTUAL ( src_seg, src_off ) ); \
100
+	} while ( 0 )
101
+#define copy_to_real copy_to_real_librm
102
+#define copy_from_real copy_from_real_librm
103
+#define put_real put_real_librm
104
+#define get_real get_real_librm
105
+
106
+/* Copy to/from real-mode stack */
107
+extern uint16_t copy_to_rm_stack ( void *data, size_t size );
108
+extern void remove_from_rm_stack ( void *data, size_t size );
109
+
110
+/* Place/remove parameter on real-mode stack in a way that's
111
+ * compatible with libkir
112
+ */
113
+#define BASEMEM_PARAMETER_INIT_LIBRM( param ) \
114
+	copy_to_rm_stack ( & ( param ), sizeof ( param ) )
115
+#define BASEMEM_PARAMETER_DONE_LIBRM( param ) \
116
+	remove_from_rm_stack ( & ( param ), sizeof ( param ) )
117
+#define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBRM
118
+#define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBRM
119
+
120
+/* REAL_FRAGMENT: Declare and define a real-mode code fragment in .text16 */
121
+#define	REAL_FRAGMENT( name, asm_code_str )				\
122
+	extern void name ( void );					\
123
+	extern char name ## _size[];					\
124
+	__asm__ __volatile__ (						\
125
+		".section \".text16\"\n\t"				\
126
+		".code16\n\t"						\
127
+		".arch i386\n\t"					\
128
+		#name ":\n\t"						\
129
+		asm_code_str "\n\t"					\
130
+		"lret\n\t"						\
131
+		#name "_end:\n\t"					\
132
+		".equ " #name "_size, " #name "_end - " #name "\n\t"	\
133
+		".code32\n\t"						\
134
+		".previous\n\t"						\
135
+		: :							\
136
+	)
137
+#define FRAGMENT_SIZE( fragment ) ( (size_t) fragment ## _size )
138
+
139
+/* REAL_CALL: call a real-mode routine via librm */
140
+#define OUT_CONSTRAINTS(...) __VA_ARGS__
141
+#define IN_CONSTRAINTS(...) "m" ( __routine ), ## __VA_ARGS__
142
+#define CLOBBER(...) __VA_ARGS__
143
+#define REAL_CALL( routine, num_out_constraints, out_constraints,	     \
144
+		   in_constraints, clobber )				     \
145
+	do {								     \
146
+		segoff_t __routine = routine;				     \
147
+		__asm__ __volatile__ (					     \
148
+				      "pushl %" #num_out_constraints "\n\t"  \
149
+				      "call 1f\n\t"			     \
150
+				      "jmp 2f\n\t"			     \
151
+				      "\n1:\n\t"			     \
152
+				      "pushl installed_librm\n\t"	     \
153
+				      "addl $_real_call, 0(%%esp)\n\t"	     \
154
+				      "ret\n\t"				     \
155
+				      "\n2:\n\t"			     \
156
+				      "addl $4, %%esp\n\t"		     \
157
+				      : out_constraints			     \
158
+				      : in_constraints			     \
159
+				      : clobber				     \
160
+				      );				     \
161
+	} while ( 0 )
162
+
163
+/* REAL_EXEC: combine RM_FRAGMENT and REAL_CALL into one handy unit */
164
+#define PASSTHRU(...) __VA_ARGS__
165
+#define REAL_EXEC( name, asm_code_str, num_out_constraints, out_constraints, \
166
+		   in_constraints, clobber )				     \
167
+	do {								     \
168
+		segoff_t fragment;					     \
169
+									     \
170
+		REAL_FRAGMENT ( name, asm_code_str );			     \
171
+									     \
172
+		fragment.segment = inst_rm_stack.segment;		     \
173
+		fragment.offset =					     \
174
+			copy_to_rm_stack ( name, FRAGMENT_SIZE ( name ) );   \
175
+									     \
176
+		REAL_CALL ( fragment, num_out_constraints,		     \
177
+			    PASSTHRU ( out_constraints ),		     \
178
+			    PASSTHRU ( in_constraints ),		     \
179
+			    PASSTHRU ( clobber ) );			     \
180
+									     \
181
+		remove_from_rm_stack ( NULL, FRAGMENT_SIZE ( name ) );	     \
182
+	} while ( 0 )
183
+
184
+#endif /* ASSEMBLY */
185
+
186
+#endif /* LIBRM_H */

+ 34
- 0
src/arch/i386/include/memsizes.h View File

@@ -0,0 +1,34 @@
1
+#ifndef MEMSIZES_H
2
+#define MEMSIZES_H
3
+
4
+/*
5
+ * These structures seem to be very i386 (and, in fact, PCBIOS)
6
+ * specific, so I've moved them out of etherboot.h.
7
+ *
8
+ */
9
+
10
+struct e820entry {
11
+	uint64_t addr;
12
+	uint64_t size;
13
+	uint32_t type;
14
+#define E820_RAM	1
15
+#define E820_RESERVED	2
16
+#define E820_ACPI	3 /* usable as RAM once ACPI tables have been read */
17
+#define E820_NVS	4
18
+} __attribute__ (( packed ));
19
+#define E820ENTRY_SIZE 20
20
+#define E820MAX 32
21
+
22
+struct meminfo {
23
+	uint16_t basememsize;
24
+	uint16_t pad;
25
+	uint32_t memsize;
26
+	uint32_t map_count;
27
+	struct e820entry map[E820MAX];
28
+} __attribute__ (( packed ));
29
+
30
+extern struct meminfo meminfo;
31
+
32
+extern void get_memsizes ( void );
33
+
34
+#endif /* MEMSIZES_H */

+ 2
- 2
src/arch/i386/include/pic8259.h View File

@@ -8,7 +8,7 @@
8 8
 #define PIC8259_H
9 9
 
10 10
 /* For segoff_t */
11
-#include "segoff.h"
11
+#include "realmode.h"
12 12
 
13 13
 #define IRQ_PIC_CUTOFF (8)
14 14
 
@@ -90,7 +90,7 @@ void dump_irq_status ( void );
90 90
  * handler code, so we put prototypes and the size macro here.
91 91
  */
92 92
 extern void _trivial_irq_handler ( void );
93
-extern void _trivial_irq_handler_end ( void );
93
+extern char _trivial_irq_handler_size[];
94 94
 #define TRIVIAL_IRQ_HANDLER_SIZE FRAGMENT_SIZE(_trivial_irq_handler)
95 95
 
96 96
 #endif /* PIC8259_H */

+ 0
- 1
src/arch/i386/include/pxe_callbacks.h View File

@@ -5,7 +5,6 @@
5 5
 #define PXE_CALLBACKS_H
6 6
 
7 7
 #include "etherboot.h"
8
-#include "segoff.h"
9 8
 #include "pxe.h"
10 9
 
11 10
 typedef struct {

+ 1
- 1
src/arch/i386/include/pxe_types.h View File

@@ -10,7 +10,7 @@
10 10
 
11 11
 /* SEGOFF16_t defined in separate header
12 12
  */
13
-#include "segoff.h"
13
+#include "realmode.h"
14 14
 typedef segoff_t I386_SEGOFF16_t;
15 15
 #define SEGOFF16_t I386_SEGOFF16_t
16 16
 

+ 109
- 109
src/arch/i386/include/realmode.h View File

@@ -1,124 +1,124 @@
1
-/* Real-mode interface
2
- */
1
+#ifndef REALMODE_H
2
+#define REALMODE_H
3 3
 
4 4
 #ifndef ASSEMBLY
5 5
 
6
-#include "etherboot.h"
7
-#include "segoff.h"
8
-
9
-typedef union {
10
-	struct {
11
-		union {
12
-			uint8_t l;
13
-			uint8_t byte;
14
-		};
15
-		uint8_t h;
16
-	} PACKED;
17
-	uint16_t word;
18
-} PACKED reg16_t;
19
-
20
-typedef union {
21
-	reg16_t w;
22
-	uint32_t dword;
23
-} PACKED reg32_t;
24
-
25
-/* Macros to help with defining inline real-mode trampoline fragments.
6
+#include "stdint.h"
7
+#include "compiler.h"
8
+#include "registers.h"
9
+#include "io.h"
10
+
11
+/*
12
+ * Data structures and type definitions
13
+ *
26 14
  */
27
-#define RM_XSTR(x) #x	/* Macro hackery needed to stringify       */
28
-#define RM_STR(x) RM_XSTR(x)
29
-#define	RM_FRAGMENT(name, asm_code_str)		\
30
-	extern void name ( void );		\
31
-	extern void name ## _end (void);	\
32
-	__asm__(				\
33
-		".section \".text16\"\n\t"	\
34
-		".code16\n\t"			\
35
-		".arch i386\n\t"		\
36
-		".globl " #name " \n\t"		\
37
-		#name ":\n\t"			\
38
-		asm_code_str "\n\t"		\
39
-		".globl " #name "_end\n\t"	\
40
-		#name "_end:\n\t"		\
41
-		".code32\n\t"			\
42
-		".previous\n\t"			\
43
-	)
44
-
45
-#define FRAGMENT_SIZE(fragment) ( (size_t) ( ( (void*) fragment ## _end )\
46
-					     - ( (void*) (fragment) ) ) )
47
-
48
-/* Data structures in _prot_to_real and _real_to_prot.  These
49
- * structures are accessed by assembly code as well as C code.
15
+
16
+/* All i386 registers, as passed in by prot_call or kir_call */
17
+struct real_mode_regs {
18
+	struct i386_all_regs;
19
+} PACKED;
20
+
21
+/* Segment:offset structure.  Note that the order within the structure
22
+ * is offset:segment.
50 23
  */
51 24
 typedef struct {
52
-	uint32_t esp;
53
-	uint16_t cs;
54
-	uint16_t ss;
55
-	uint32_t r2p_params;
56
-} PACKED prot_to_real_params_t;
25
+	uint16_t offset;
26
+	uint16_t segment;
27
+} segoff_t PACKED;
57 28
 
58
-typedef struct {
59
-	uint32_t ret_addr;
60
-	uint32_t esp;
61
-	uint32_t ebx;
62
-	uint32_t esi;
63
-	uint32_t edi;
64
-	uint32_t ebp;
65
-	uint32_t out_stack;
66
-	uint32_t out_stack_len;
67
-} PACKED real_to_prot_params_t;
68
-
69
-/* Function prototypes: realmode.c
29
+/* Macro hackery needed to stringify bits of inline assembly */
30
+#define RM_XSTR(x) #x
31
+#define RM_STR(x) RM_XSTR(x)
32
+
33
+/* Drag in the selected real-mode transition library header */
34
+#ifdef KEEP_IT_REAL
35
+#include "libkir.h"
36
+#else
37
+#include "librm.h"
38
+#endif
39
+
40
+/*
41
+ * The API to some functions is identical between librm and libkir, so
42
+ * they are documented here, even though the prototypes are in librm.h
43
+ * and libkir.h.
44
+ *
70 45
  */
71
-#define real_call( fragment, in_stack, out_stack ) \
72
-	_real_call ( fragment, FRAGMENT_SIZE(fragment), \
73
-		     (void*)(in_stack), \
74
-		     ( (in_stack) == NULL ? 0 : sizeof(*(in_stack)) ), \
75
-		     (void*)(out_stack), \
76
-		     ( (out_stack) == NULL ? 0 : sizeof(*(out_stack)) ) )
77
-extern uint16_t _real_call ( void *fragment, int fragment_len,
78
-			     void *in_stack, int in_stack_len,
79
-			     void *out_stack, int out_stack_len );
80
-/* Function prototypes: realmode_asm.S
46
+
47
+/*
48
+ * void copy_to_real ( uint16_t dest_seg, uint16_t dest_off,
49
+ *		       void *src, size_t n )
50
+ * void copy_from_real ( void *dest, uint16_t src_seg, uint16_t src_off,
51
+ *			 size_t n )
52
+ *
53
+ * These functions can be used to copy data to and from arbitrary
54
+ * locations in base memory.
81 55
  */
82
-extern void rm_callback_interface;
83
-extern uint16_t rm_callback_interface_size;
84
-extern uint32_t rm_etherboot_location;
85
-extern void _rm_in_call ( void );
86
-extern void _rm_in_call_far ( void );
87
-
88
-extern void _prot_to_real_prefix ( void );
89
-extern void _prot_to_real_prefix_end ( void );
90
-extern uint16_t prot_to_real_prefix_size;
91
-
92
-extern void _real_to_prot_suffix ( void );
93
-extern void _real_to_prot_suffix_end ( void );
94
-extern uint16_t real_to_prot_suffix_size;
95
-
96
-/* PXE assembler bits */
97
-extern void pxe_callback_interface;
98
-extern uint16_t pxe_callback_interface_size;
99
-extern void _pxe_in_call_far ( void );
100
-extern void _pxenv_in_call_far ( void );
101
-extern void _pxe_intercept_int1a ( void );
102
-extern segoff_t _pxe_intercepted_int1a;
103
-extern segoff_t _pxe_pxenv_location;
104
-
105
-/* Global variables
56
+
57
+/*
58
+ * put_real ( variable, uint16_t dest_seg, uint16_t dest_off )
59
+ * get_real ( variable, uint16_t src_seg, uint16_t src_off )
60
+ *
61
+ * These macros can be used to read or write single variables to and
62
+ * from arbitrary locations in base memory.  "variable" must be a
63
+ * variable of either 1, 2 or 4 bytes in length.
106 64
  */
107
-extern uint32_t real_mode_stack;
108
-extern size_t real_mode_stack_size;
65
+
66
+/*
67
+ * REAL_CALL ( routine, num_out_constraints, out_constraints,
68
+ *	       in_constraints, clobber )
69
+ * REAL_EXEC ( name, asm_code_str, num_out_constraints, out_constraints,
70
+ *	       in_constraints, clobber )
71
+ *
72
+ * If you have a pre-existing real-mode routine that you want to make
73
+ * a far call to, use REAL_CALL.  If you have a code fragment that you
74
+ * want to copy down to base memory, execute, and then remove, use
75
+ * REAL_EXEC.
76
+ *
77
+ * out_constraints must be of the form OUT_CONSTRAINTS(constraints),
78
+ * and in_constraints must be of the form IN_CONSTRAINTS(constraints),
79
+ * where "constraints" is a constraints list as would be used in an
80
+ * inline __asm__()
81
+ *
82
+ * clobber must be of the form CLOBBER ( clobber_list ), where
83
+ * "clobber_list" is a clobber list as would be used in an inline
84
+ * __asm__().
85
+ *
86
+ * These are best illustrated by example.  To write a character to the
87
+ * console using INT 10, you would do something like:
88
+ *
89
+ *	REAL_EXEC ( rm_test_librm,
90
+ *		    "int $0x10",
91
+ *		    1,
92
+ *		    OUT_CONSTRAINTS ( "=a" ( discard ) ),
93
+ *		    IN_CONSTRAINTS ( "a" ( 0x0e00 + character ),
94
+ *				     "b" ( 1 ) ),
95
+ *		    CLOBBER ( "ebx", "ecx", "edx", "ebp", "esi", "edi" ) );
96
+ *
97
+ * IMPORTANT: gcc does not automatically assume that input operands
98
+ * get clobbered.  The only way to specify that an input operand may
99
+ * be modified is to also specify it as an output operand; hence the
100
+ * "(discard)" in the above code.
101
+ */
102
+
103
+#warning "realmode.h contains placeholders for obsolete macros"
104
+
105
+
106
+/* Just for now */
107
+#define SEGMENT(x) ( virt_to_phys ( x ) >> 4 )
108
+#define OFFSET(x) ( virt_to_phys ( x ) & 0xf )
109
+#define SEGOFF(x) { OFFSET(x), SEGMENT(x) }
110
+
111
+/* To make basemem.c compile */
109 112
 extern int lock_real_mode_stack;
113
+extern char *real_mode_stack;
114
+extern char real_mode_stack_size[];
115
+
116
+#define RM_FRAGMENT(name,asm) \
117
+	void name ( void ) {} \
118
+	extern char name ## _size[];
110 119
 
111 120
 
112
-/* Function prototypes from basemem.c
113
- */
114
-#ifdef LINUXBIOS
115
-/* A silly hard code that let's the code compile and work. 
116
- * When this becomes a problem feel free to implement
117
- * something better.
118
- */
119
-static inline void allot_real_mode_stack(void) { real_mode_stack = 0x7c00; } 
120
-#else
121
-void allot_real_mode_stack(void);
122
-#endif
123 121
 
124 122
 #endif /* ASSEMBLY */
123
+
124
+#endif /* REALMODE_H */

+ 93
- 0
src/arch/i386/include/registers.h View File

@@ -0,0 +1,93 @@
1
+#ifndef REGISTERS_H
2
+#define REGISTERS_H
3
+
4
+#include "stdint.h"
5
+#include "compiler.h"
6
+
7
+/* Basic 16-bit and 32-bit register types */
8
+typedef union {
9
+	struct {
10
+		union {
11
+			uint8_t l;
12
+			uint8_t byte;
13
+		};
14
+		uint8_t h;
15
+	} PACKED;
16
+	uint16_t word;
17
+} PACKED reg16_t;
18
+
19
+typedef union {
20
+	reg16_t;
21
+	uint32_t dword;
22
+} PACKED reg32_t;
23
+
24
+/* As created by pushal / read by popal */
25
+struct i386_regs {
26
+	union {
27
+		uint16_t di;
28
+		uint32_t edi;
29
+	};
30
+	union {
31
+		uint16_t si;
32
+		uint32_t esi;
33
+	};
34
+	union {
35
+		uint16_t bp;
36
+		uint32_t ebp;
37
+	};
38
+	union {
39
+		uint16_t sp;
40
+		uint32_t esp;
41
+	};
42
+	union {
43
+		struct {
44
+			uint8_t bl;
45
+			uint8_t bh;
46
+		} PACKED;
47
+		uint16_t bx;
48
+		uint32_t ebx;
49
+	};
50
+	union {
51
+		struct {
52
+			uint8_t dl;
53
+			uint8_t dh;
54
+		} PACKED;
55
+		uint16_t dx;
56
+		uint32_t edx;
57
+	};
58
+	union {
59
+		struct {
60
+			uint8_t cl;
61
+			uint8_t ch;
62
+		} PACKED;
63
+		uint16_t cx;
64
+		uint32_t ecx;
65
+	};
66
+	union {
67
+		struct {
68
+			uint8_t al;
69
+			uint8_t ah;
70
+		} PACKED;
71
+		uint16_t ax;
72
+		uint32_t eax;
73
+	};
74
+} PACKED;
75
+
76
+/* Our pushal/popal equivalent for segment registers */
77
+struct i386_seg_regs {
78
+	uint16_t cs;
79
+	uint16_t ss;
80
+	uint16_t ds;
81
+	uint16_t es;
82
+	uint16_t fs;
83
+	uint16_t gs;
84
+} PACKED;
85
+
86
+/* All i386 registers, as passed in by prot_call or kir_call */
87
+struct i386_all_regs {
88
+	struct i386_seg_regs;
89
+	struct i386_regs;
90
+	uint32_t i386_flags;
91
+} PACKED;
92
+
93
+#endif /* REGISTERS_H */

+ 0
- 41
src/arch/i386/include/segoff.h View File

@@ -1,41 +0,0 @@
1
-/*
2
- * Segment:offset types and macros
3
- *
4
- * Initially written by Michael Brown (mcb30).
5
- */
6
-
7
-#ifndef SEGOFF_H
8
-#define SEGOFF_H
9
-
10
-#include <stdint.h>
11
-#include <osdep.h>
12
-#include <io.h>
13
-
14
-/* Segment:offset structure.  Note that the order within the structure
15
- * is offset:segment.
16
- */
17
-typedef struct {
18
-	uint16_t offset;
19
-	uint16_t segment;
20
-} segoff_t;
21
-
22
-/* Macros for converting from virtual to segment:offset addresses,
23
- * when we don't actually care which of the many isomorphic results we
24
- * get.
25
- */
26
-#ifdef DEBUG_SEGMENT
27
-uint16_t SEGMENT ( const void * const ptr ) {
28
-	uint32_t phys = virt_to_phys ( ptr );
29
-	if ( phys > 0xfffff ) {
30
-		printf ( "FATAL ERROR: segment address out of range\n" );
31
-	}
32
-	return phys >> 4;
33
-}
34
-#else
35
-#define SEGMENT(x) ( virt_to_phys ( x ) >> 4 )
36
-#endif
37
-#define OFFSET(x) ( virt_to_phys ( x ) & 0xf )
38
-#define SEGOFF(x) { OFFSET(x), SEGMENT(x) }
39
-#define VIRTUAL(x,y) ( phys_to_virt ( ( ( x ) << 4 ) + ( y ) ) )
40
-
41
-#endif /* SEGOFF_H */

+ 85
- 0
src/arch/i386/include/virtaddr.h View File

@@ -0,0 +1,85 @@
1
+#ifndef VIRTADDR_H
2
+#define VIRTADDR_H
3
+
4
+/* Segment selectors as used in our protected-mode GDTs.
5
+ *
6
+ * Don't change these unless you really know what you're doing.
7
+ */
8
+#define PHYSICAL_CS 0x08
9
+#define PHYSICAL_DS 0x10
10
+#define VIRTUAL_CS 0x18
11
+#define VIRTUAL_DS 0x20
12
+#define LONG_CS 0x28
13
+#define LONG_DS 0x30
14
+
15
+#ifndef ASSEMBLY
16
+
17
+#include "stdint.h"
18
+
19
+#ifndef KEEP_IT_REAL
20
+
21
+/*
22
+ * Without -DKEEP_IT_REAL, we are in 32-bit protected mode with a
23
+ * fixed link address but an unknown physical start address.  Our GDT
24
+ * sets up code and data segments with an offset of virt_offset, so
25
+ * that link-time addresses can still work.
26
+ *
27
+ */
28
+
29
+/* C-callable function prototypes */
30
+
31
+extern void relocate_to ( uint32_t new_phys_addr );
32
+
33
+/* Variables in virtaddr.S */
34
+extern unsigned long virt_offset;
35
+
36
+/*
37
+ * Convert between virtual and physical addresses
38
+ *
39
+ */
40
+static inline unsigned long virt_to_phys ( volatile const void *virt_addr ) {
41
+	return ( ( unsigned long ) virt_addr ) + virt_offset;
42
+}
43
+
44
+static inline void * phys_to_virt ( unsigned long phys_addr ) {
45
+	return ( void * ) ( phys_addr - virt_offset );
46
+}
47
+
48
+#else /* KEEP_IT_REAL */
49
+
50
+/*
51
+ * With -DKEEP_IT_REAL, we are in 16-bit real mode with fixed link
52
+ * addresses and a segmented memory model.  We have separate code and
53
+ * data segments.
54
+ *
55
+ * Because we may be called in 16-bit protected mode (damn PXE spec),
56
+ * we cannot simply assume that physical = segment * 16 + offset.
57
+ * Instead, we have to look up the physical start address of the
58
+ * segment in the !PXE structure.  We have to assume that
59
+ * virt_to_phys() is called only on pointers within the data segment,
60
+ * because nothing passes segment information to us.
61
+ *
62
+ * We don't implement phys_to_virt at all, because there will be many
63
+ * addresses that simply cannot be reached via a virtual address when
64
+ * the virtual address space is limited to 64kB!
65
+ */
66
+
67
+static inline unsigned long virt_to_phys ( volatile const void *virt_addr ) {
68
+	/* Cheat: just for now, do the segment*16+offset calculation */
69
+	uint16_t ds;
70
+
71
+	__asm__ ( "movw %%ds, %%ax" : "=a" ( ds ) : );
72
+	return ( 16 * ds + ( ( unsigned long ) virt_addr ) );
73
+}
74
+
75
+/* Define it as a deprecated function so that we get compile-time
76
+ * warnings, rather than just the link-time errors.
77
+ */
78
+extern void * phys_to_virt ( unsigned long phys_addr )
79
+     __attribute__ ((deprecated));
80
+
81
+#endif /* KEEP_IT_REAL */
82
+
83
+#endif /* ASSEMBLY */
84
+
85
+#endif /* VIRTADDR_H */

+ 29
- 0
src/arch/i386/kir-Makefile View File

@@ -0,0 +1,29 @@
1
+# Makefile to build a KEEP_IT_REAL flavour
2
+# 
3
+# KEEP_IT_REAL, by its nature, requires a different build of every
4
+# single object file, since the inclusion of ".code16gcc" will
5
+# generate different machine code from the assembly.  Unlike the other
6
+# config options, there is no way that this global dependency can ever
7
+# be reduced, so it makes sense to be able to build both the normal
8
+# and the KIR versions without having to force a full rebuild each
9
+# time.
10
+
11
+# Add this Makefile to MAKEDEPS
12
+#
13
+MAKEDEPS	+= arch/i386/kir-Makefile
14
+
15
+# Place binaries in bin-kir
16
+#
17
+BIN		= bin-kir
18
+
19
+# Compile with -DKEEP_IT_REAL, forcibly include kir.h at the start of
20
+# each file to drag in ".code16gcc"
21
+#
22
+CFLAGS		+= -DKEEP_IT_REAL -include kir.h
23
+
24
+# Link with _data_link_addr = 0; data symbols are relative to the data
25
+# segment.
26
+#
27
+LDFLAGS		+= --defsym _data_link_addr=0
28
+
29
+include Makefile

src/arch/i386/prefix/floppyprefix.S → src/arch/i386/prefix/dskprefix.S View File

@@ -1,3 +1,5 @@
1
+#include "compiler.h"
2
+
1 3
 /* NOTE: this boot sector contains instructions that need at least an 80186.
2 4
  * Yes, as86 has a bug somewhere in the valid instruction set checks.
3 5
  *
@@ -115,7 +117,6 @@ got_sectors:
115 117
 
116 118
 /* ok, we've written the Loading... message, now we want to load the system */
117 119
 
118
-	pushw	%es			/* = ds */
119 120
 	movw	$SYSSEG, %ax
120 121
 	movw	%ax,%es			/* segment of SYSSEG<<4 */
121 122
 	pushw	%es
@@ -130,8 +131,6 @@ got_sectors:
130 131
 
131 132
 	call	print_nl
132 133
 	pop	%es			/* = SYSSEG */
133
-	pop	%es			/* balance push/pop es */
134
-sigok: 
135 134
 
136 135
 /* Restore original disk parameters */
137 136
 	movw	$0x78, %bx
@@ -142,20 +141,47 @@ sigok:
142 141
 	movw	%di,(%bx)
143 142
 	movw	%si,2(%bx)
144 143
 
145
-/* after that (everything loaded), we call to the .ROM file loaded. */
146
-
147
-	pushl	$0		/* No parameters to preserve for exit path */
148
-	pushw	$0		/* Use prefix exit path mechanism */
149
-	ljmp	$SYSSEG, $_start
150
-
151
-	.section ".text16", "ax", @progbits
152
-	.globl	prefix_exit
153
-prefix_exit:
154
-	xchgw	%bx, %bx
155
-	int	$0x19		/* should try to boot machine */
156
-	.globl	prefix_exit_end
157
-prefix_exit_end:
158
-	.previous
144
+	/* Everything now loaded.  %es = SYSSEG, so %es:0000 points to
145
+	 * start of loaded image.
146
+	 */
147
+
148
+start_runtime:
149
+
150
+#ifdef	COMPRESS
151
+	/* Decompress runtime image.  %es:0000 points to decompressed
152
+	 * image on exit.
153
+	 */
154
+	lcall	$SYSSEG, $decompress16
155
+#endif
156
+	
157
+	/* Set up internal environment.  Address of entry-point
158
+	 * function is returned in %es:di.
159
+	 */
160
+	pushw	%es		/* setup16 says %ds:0000 must point to image */
161
+	popw	%ds
162
+	movw	$setup16, %di
163
+	pushw	%cs
164
+	call	ljmp_to_es_di
165
+
166
+	/* Call initialisation routine.  Relocation may be done.  New
167
+	 * address of entry-point function is returned in %es:di.
168
+	 */
169
+	pushl	$arch_rm_initialise
170
+	pushw	%cs		/* == lcall %es:di */
171
+	call	ljmp_to_es_di
172
+	
173
+	/* Call to arch_rm_main.  Register INT19 as an exit path.  This
174
+	 * call will never return.
175
+	 */
176
+	movl	$exit_via_int19, %eax
177
+	pushl	$arch_rm_main
178
+	pushl	%eax		/* Dummy return address */
179
+
180
+	/* Do the equivalent of ljmp *%es:di */
181
+ljmp_to_es_di:	
182
+	pushw	%es
183
+	pushw	%di
184
+	lret
159 185
 
160 186
 /* This routine loads the system at address SYSSEG<<4, making sure no 64kB
161 187
  * boundaries are crossed. We try to load it as fast as possible, loading whole
@@ -164,7 +190,7 @@ prefix_exit_end:
164 190
  * in:	es - starting address segment (normally SYSSEG)
165 191
  */
166 192
 read_it: 
167
-	movw	$0,sread		/* read whole image incl boot sector */
193
+	movw	$1,sread		/* don't reload the prefix */
168 194
 	movw	%es,%ax
169 195
 	testw	$0x0fff, %ax
170 196
 die:	jne	die			/* es must be at 64kB boundary */

+ 13
- 0
src/arch/i386/prefix/int19exit.c View File

@@ -0,0 +1,13 @@
1
+#include "bochs.h"
2
+#include "realmode.h"
3
+
4
+/*
5
+ * The "exit via INT 19" exit path.  INT 19 is the old (pre-BBS) "boot
6
+ * system" interrupt.
7
+ *
8
+ */
9
+
10
+void exit_via_int19 ( struct real_mode_regs *rm_regs ) {
11
+	bochsbp();
12
+	/* Placeholder */
13
+}

+ 121
- 77
src/arch/i386/prefix/unnrv2b.S View File

@@ -15,115 +15,159 @@
15 15
  * - Structure modified to be a subroutine call rather than an
16 16
  *   executable prefix.
17 17
  *   Michael Brown 30 Mar 2004
18
+ *
19
+ * - Modified to be compilable as either 16-bit or 32-bit code.
20
+ *   Michael Brown 9 Mar 2005
18 21
  */
19 22
 
23
+/****************************************************************************
24
+ * This file provides the decompress_block() and decompress_block16()
25
+ * functions which can be called in order to decompress an image
26
+ * compressed with the nrv2b utility in src/util.
27
+ *
28
+ * These functions are designed to be called by the prefix.  They are
29
+ * position-independent code.
30
+ *
31
+ * The same basic assembly code is used to compile both
32
+ * decompress_block() and decompress_block16().
33
+ ****************************************************************************
34
+ */
20 35
 
21 36
 	.text
22 37
 	.arch i386
23 38
 	.section ".prefix", "ax", @progbits
24
-	.code32
25
-	
26
-	.globl decompress
27
-decompress:
28
-	/* Save the initial register values */
29
-	pushal
30 39
 
31
-	/*
32
-	 * See where I am running, and compute %ebp
33
-	 * %ebp holds delta between physical and virtual addresses.
34
-	 */
35
-	call	1f
36
-1:	popl	%ebp
37
-	subl	$1b, %ebp
40
+#ifdef CODE16
41
+/****************************************************************************
42
+ * decompress_block16 (real-mode near call, position independent)
43
+ *
44
+ * Parameters (passed via registers):
45
+ *   %ds:%si - Pointer to compressed input data
46
+ *   %es:%di - Pointer to output buffer
47
+ * Returns:
48
+ *   All registers are preserved
49
+ *
50
+ * NOTE: The compressed data size must be in the range [1,65533-%si]
51
+ * and the uncompressed data size must be in the range [1,65536-%di]
52
+ * (where %si and %di are the input values for those registers).  Note
53
+ * particularly that the lower limit is 1, not 0, and that the upper
54
+ * limit on the input (compressed) data really is 65533, since the
55
+ * algorithm may read up to three bytes beyond the end of the input
56
+ * data, since it reads dwords.
57
+ *
58
+ * Although splitting up the data into (almost) 64kB chunks for
59
+ * compression is awkward and worsens the compression ratio, it has
60
+ * little to no practical effect since our image size is currently
61
+ * <64kB for all single drivers.  Having a decompression routine that
62
+ * can run in real-mode avoids the need to duplicate RM-to-PM
63
+ * transition code from librm (or have part of librm kept
64
+ * uncompressed, which is itself awkward) and means that we don't need
65
+ * to set up the PM stack until we hit the setup routine itself.
66
+ ****************************************************************************
67
+ */
68
+
69
+#define REG(x) x
38 70
 
39
-	/* "compressed" and "decompress_to" defined by linker script */
40
-	/* move compressed image up to temporary area before decompressing */
41
-	std
42
-	movl	$_compressed_size, %ecx
43
-	leal	_compressed+4-1(%ebp, %ecx), %esi
44
-	leal	_compressed_copy-1(%ebp, %ecx), %edi
45
-	rep movsb
46
-	/* Setup to run the decompressor */
47
-	cld
48
-	leal	_compressed_copy(%ebp), %esi
49
-	leal	decompress_to(%ebp), %edi
50
-	movl	$-1, %ebp	/* last_m_off = -1 */
51
-	jmp	dcl1_n2b
71
+	.code16
72
+	.globl	decompress_block16
73
+decompress_block16:
74
+	
75
+#else /* CODE16 */
52 76
 
53
-/* ------------- DECOMPRESSION -------------
77
+/****************************************************************************
78
+ * decompress_block (32-bit protected-mode near call, position independent)
79
+ *
80
+ * Parameters (passed via registers):
81
+ *   %ds:%esi - Pointer to compressed input data
82
+ *   %es:%edi - Pointer to output buffer
83
+ * Returns:
84
+ *   All registers are preserved
85
+ ****************************************************************************
86
+ */
54 87
 
55
- Input:
56
-   %esi - source
57
-   %edi - dest
58
-   %ebp - -1
59
-   cld
88
+#define REG(x) e ## x
89
+	
90
+	.code32
91
+	.globl	decompress_block
92
+decompress_block:
60 93
 
61
- Output:
62
-   %eax - 0
63
-   %ecx - 0
64
-*/
94
+#endif /* CODE16 */
65 95
 
66
-.macro getbit bits
67
-.if	\bits == 1
68
-	addl	%ebx, %ebx
69
-	jnz	1f
70
-.endif
71
-	movl	(%esi), %ebx
72
-	subl	$-4, %esi	/* sets carry flag */
73
-	adcl	%ebx, %ebx
74
-1:
75
-.endm
96
+#define xAX	REG(ax)
97
+#define xCX	REG(cx)
98
+#define xBP	REG(bp)
99
+#define xSI	REG(si)
100
+#define xDI	REG(di)
76 101
 
102
+	/* Save registers */
103
+	pushal
104
+	/* Do the decompression */
105
+	cld
106
+	xor	%xBP, %xBP
107
+	dec	%xBP		/* last_m_off = -1 */
108
+	jmp	dcl1_n2b
109
+	
77 110
 decompr_literals_n2b:
78 111
 	movsb
79
-
80 112
 decompr_loop_n2b:
81 113
 	addl	%ebx, %ebx
82 114
 	jnz	dcl2_n2b
83 115
 dcl1_n2b:
84
-	getbit	32
116
+	call	getbit32
85 117
 dcl2_n2b:
86 118
 	jc	decompr_literals_n2b
87
-	xorl	%eax, %eax
88
-	incl	%eax		/* m_off = 1 */
119
+	xor	%xAX, %xAX
120
+	inc	%xAX		/* m_off = 1 */
89 121
 loop1_n2b:
90
-	getbit	1
91
-	adcl	%eax, %eax	/* m_off = m_off*2 + getbit() */
92
-	getbit	1
122
+	call	getbit1
123
+	adc	%xAX, %xAX	/* m_off = m_off*2 + getbit() */
124
+	call	getbit1
93 125
 	jnc	loop1_n2b	/* while(!getbit()) */
94
-	xorl	%ecx, %ecx
95
-	subl	$3, %eax
126
+	sub	$3, %xAX
96 127
 	jb	decompr_ebpeax_n2b	/* if (m_off == 2) goto decompr_ebpeax_n2b ? */
97
-	shll	$8, %eax	
98
-	movb	(%esi), %al	/* m_off = (m_off - 3)*256 + src[ilen++] */
99
-	incl	%esi
100
-	xorl	$-1, %eax	
128
+	shl	$8, %xAX	
129
+	movb	(%xSI), %al	/* m_off = (m_off - 3)*256 + src[ilen++] */
130
+	inc	%xSI
131
+	not	%xAX	
101 132
 	jz	decompr_end_n2b	/* if (m_off == 0xffffffff) goto decomp_end_n2b */
102
-	movl	%eax, %ebp	/* last_m_off = m_off ?*/
133
+	mov	%xAX, %xBP	/* last_m_off = m_off ?*/
103 134
 decompr_ebpeax_n2b:
104
-	getbit	1		
105
-	adcl	%ecx, %ecx	/* m_len = getbit() */
106
-	getbit	1
107
-	adcl	%ecx, %ecx	/* m_len = m_len*2 + getbit()) */
135
+	xor	%xCX, %xCX
136
+	call	getbit1
137
+	adc	%xCX, %xCX	/* m_len = getbit() */
138
+	call	getbit1
139
+	adc	%xCX, %xCX	/* m_len = m_len*2 + getbit()) */
108 140
 	jnz	decompr_got_mlen_n2b	/* if (m_len == 0) goto decompr_got_mlen_n2b */
109
-	incl	%ecx		/* m_len++ */
141
+	inc	%xCX		/* m_len++ */
110 142
 loop2_n2b:
111
-	getbit	1	
112
-	adcl	%ecx, %ecx	/* m_len = m_len*2 + getbit() */
113
-	getbit	1
143
+	call	getbit1	
144
+	adc	%xCX, %xCX	/* m_len = m_len*2 + getbit() */
145
+	call	getbit1
114 146
 	jnc	loop2_n2b	/* while(!getbit()) */
115
-	incl	%ecx
116
-	incl	%ecx		/* m_len += 2 */
147
+	inc	%xCX
148
+	inc	%xCX		/* m_len += 2 */
117 149
 decompr_got_mlen_n2b:
118
-	cmpl	$-0xd00, %ebp
119
-	adcl	$1, %ecx	/* m_len = m_len + 1 + (last_m_off > 0xd00) */
120
-	pushl	%esi
121
-	leal	(%edi,%ebp), %esi	/* m_pos = dst + olen + -m_off  */
150
+	cmp	$-0xd00, %xBP
151
+	adc	$1, %xCX	/* m_len = m_len + 1 + (last_m_off > 0xd00) */
152
+	push	%xSI
153
+	lea	(%xBP,%xDI), %xSI	/* m_pos = dst + olen + -m_off  */
122 154
 	rep
123
-	movsb			/* dst[olen++] = *m_pos++ while(m_len > 0) */
124
-	popl	%esi
155
+	es movsb		/* dst[olen++] = *m_pos++ while(m_len > 0) */
156
+	pop	%xSI
125 157
 	jmp	decompr_loop_n2b
158
+
159
+
160
+getbit1:
161
+	addl	%ebx, %ebx
162
+	jnz	1f
163
+getbit32:
164
+	movl	(%xSI), %ebx
165
+	sub	$-4, %xSI	/* sets carry flag */
166
+	adcl	%ebx, %ebx
167
+1:
168
+	ret
169
+
126 170
 decompr_end_n2b:
127
-	/* Restore the initial register values */
171
+	/* Restore registers and return */
128 172
 	popal
129 173
 	ret

+ 263
- 0
src/arch/i386/scripts/i386.lds View File

@@ -0,0 +1,263 @@
1
+/* -*- sh -*- */
2
+
3
+/*
4
+ * Linker script for i386 images
5
+ *
6
+ */
7
+
8
+OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
9
+OUTPUT_ARCH ( i386 )
10
+ENTRY ( _entry )
11
+
12
+SECTIONS {
13
+
14
+    /* All sections in the resulting file have consecutive load
15
+     * addresses, but may have individual link addresses depending on
16
+     * the memory model being used.
17
+     *
18
+     * The linker symbols {prefix,decompress,text,data}_link_addr,
19
+     * load_addr, and _max_align may be specified explicitly.  If not
20
+     * specified, they will default to:
21
+     *
22
+     *   _prefix_link_addr	= 0
23
+     *   _decompress_link_addr	= 0
24
+     *   _text_link_addr	= 0
25
+     *   _data_link_addr	= _text_link_addr + sizeof ( text sections )
26
+     *   _load_addr		= 0
27
+     *   _max_align		= 16
28
+     * 
29
+     * We guarantee alignment of virtual addresses to any alignment
30
+     * specified by the constituent object files (e.g. via
31
+     * __attribute__((aligned(x)))).  Load addresses are guaranteed
32
+     * only up to _max_align.  Provided that all loader and relocation
33
+     * code honours _max_align, this means that physical addresses are
34
+     * also guaranteed up to _max_align.
35
+     *
36
+     * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
37
+     * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
38
+     * alignment).  Using _max_align>16 will therefore not guarantee
39
+     * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
40
+     * used (though virtual addresses will still be fully aligned).
41
+     *
42
+     * The real-mode prefixes rely on _text_link_addr and
43
+     * _decompress_link_addr being 0, since they issue far calls into
44
+     * those sections, thus requiring that symbol_value ==
45
+     * symbol_offset therein.  Using the linker to calculate
46
+     * e.g. offset_setup16=setup16-_text will not work, since you then
47
+     * cannot use the reference from the prefix to setup16 to drag in
48
+     * setup16.o.  Life is hard.
49
+     *
50
+     * If librm is included, then it must go at offset 0 within the
51
+     * text section.  This is because librm is dual-usage: it is
52
+     * called from setup16 with %cs:0000 pointing to the start of the
53
+     * text section, and later it will be copied to base memory and
54
+     * called with %cs:0000 pointing to the start of librm.
55
+     *
56
+     * The decompressor is designed to decompress in-place.  After
57
+     * calling the decompressor, the image will look exactly the same
58
+     * as the uncompressed image; the compressed data and the
59
+     * decompressor code itself will have been overwritten.
60
+     */
61
+
62
+    /*
63
+     * The prefix
64
+     */
65
+
66
+    _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0;
67
+    . = _prefix_link_addr;
68
+    _prefix = .;
69
+
70
+    .prefix : AT ( _prefix_load_offset + __prefix ) {
71
+	__prefix = .;
72
+	_entry = .;
73
+	*(.prefix)
74
+	*(.prefix.*)
75
+    }
76
+    
77
+    _eprefix = .;
78
+
79
+    /*
80
+     * The decompressor (may be absent)
81
+     */
82
+
83
+    _decompress_link_addr = DEFINED ( _decompress_link_addr ) ?
84
+			      _decompress_link_addr : 0;
85
+    . = _decompress_link_addr;
86
+    _decompress = .;
87
+
88
+    .decompress : AT ( _decompress_load_offset + __decompress ) {
89
+	    __decompress = .;
90
+	    *(.decompress)
91
+	    *(.decompress.*)
92
+    }
93
+
94
+    _edecompress = .;
95
+
96
+    /*
97
+     * The text sections
98
+     */
99
+
100
+    _text_link_addr = DEFINED ( _text_link_addr ) ? _text_link_addr : 0;
101
+    . = _text_link_addr;
102
+    _text = .;
103
+
104
+    .text16 : AT ( _text_load_offset + __text16 ) {
105
+	__text16 = .;
106
+
107
+	/* librm is a special case; it must go at the start of the
108
+	 * text section if it is included.
109
+	 */
110
+	_assert = ASSERT ( ( . == _text_link_addr ), "librm cannot go first" );
111
+	*(.librm)
112
+
113
+	*(.text16)
114
+	*(.text16.*)
115
+    } = 0x9090
116
+
117
+    .text : AT ( _text_load_offset + __text ) {
118
+	__text = .;
119
+	*(.text)
120
+	*(.text.*)
121
+    } = 0x9090
122
+
123
+    _etext = .;
124
+
125
+    /*
126
+     * The data sections
127
+     */
128
+
129
+    _data_link_addr = DEFINED ( _data_link_addr ) ? _data_link_addr : .;
130
+    . = _data_link_addr;
131
+    _data = .;
132
+
133
+    .rodata : AT ( _data_load_offset + __rodata ) {
134
+	__rodata = .;
135
+	*(.rodata)
136
+	*(.rodata.*)
137
+    }
138
+
139
+    .data : AT ( _data_load_offset + __data ) {
140
+	__data = .;
141
+	*(.data)
142
+	*(.data.*)
143
+	pci_drivers = .;
144
+	*(.drivers.pci)
145
+	pci_drivers_end = .;
146
+	isa_drivers = .;
147
+	*(.drivers.isa)
148
+	isa_drivers_end = .;
149
+	console_drivers = .;
150
+	*(.drivers.console)
151
+	console_drivers_end = .;
152
+	init_fns = .;
153
+	*(SORT(.init_fns.*))
154
+	init_fns_end = .;
155
+
156
+	_progbits_end = .;
157
+    }
158
+
159
+    .bss : AT ( _data_load_offset + __bss ) {
160
+	__bss = .;
161
+	_bss = .;
162
+	*(.bss)
163
+	*(.bss.*)
164
+	*(COMMON)
165
+	_ebss = .;
166
+    }
167
+
168
+    .stack : AT ( _data_load_offset + __stack ) {
169
+	__stack = .;
170
+	*(.stack)
171
+	*(.stack.*)
172
+    }
173
+
174
+    _edata = .;
175
+
176
+    _end = .;
177
+
178
+    /*
179
+     * Dispose of the comment and note sections to make the link map
180
+     * easier to read
181
+     */
182
+
183
+    /DISCARD/ : {
184
+	*(.comment)
185
+	*(.note)
186
+    }
187
+
188
+    /*
189
+     * Load address calculations.  The slightly obscure nature of the
190
+     * calculations is because ALIGN(x) can only operate on the
191
+     * location counter.
192
+     */
193
+
194
+    _max_align		    = DEFINED ( _max_align ) ? _max_align : 16;
195
+    _load_addr		    = DEFINED ( _load_addr ) ? _load_addr : 0;
196
+
197
+    .			    = _load_addr;
198
+
199
+    .			   -= _prefix_link_addr;
200
+    _prefix_load_offset	    = ALIGN ( _max_align );
201
+    _prefix_load_addr	    = _prefix_link_addr + _prefix_load_offset;
202
+    _prefix_size	    = _eprefix - _prefix;
203
+    .			    = _prefix_load_addr + _prefix_size;
204
+
205
+    .			   -= _decompress_link_addr;
206
+    _decompress_load_offset = ALIGN ( _max_align );
207
+    _decompress_load_addr   = _decompress_link_addr + _decompress_load_offset;
208
+    _decompress_size	    = _edecompress - _decompress;
209
+    .			    = _decompress_load_addr + _decompress_size;
210
+
211
+    .			   -= _text_link_addr;
212
+    _text_load_offset	    = ALIGN ( _max_align );
213
+    _text_load_addr	    = _text_link_addr + _text_load_offset;
214
+    _text_size		    = _etext - _text;
215
+    .			    = _text_load_addr + _text_size;
216
+
217
+    .			   -= _data_link_addr;
218
+    _data_load_offset	    = ALIGN ( _max_align );
219
+    _data_load_addr	    = _data_link_addr + _data_load_offset;
220
+    _data_size		    = _edata - _data;
221
+    .			    = _data_load_addr + _data_size;
222
+
223
+    /*
224
+     * Alignment checks.  ALIGN() can only operate on the location
225
+     * counter, so we set the location counter to each value we want
226
+     * to check.
227
+     */
228
+
229
+    . = _prefix_load_addr - _prefix_link_addr;
230
+    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
231
+		       "_prefix is badly aligned" );
232
+
233
+    . = _decompress_load_addr - _prefix_link_addr;
234
+    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
235
+		       "_decompress is badly aligned" );
236
+
237
+    . = _text_load_addr - _text_link_addr;
238
+    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
239
+		       "_text is badly aligned" );
240
+
241
+    . = _data_load_addr - _data_link_addr;
242
+    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
243
+		       "_data is badly aligned" );
244
+
245
+    /*
246
+     * setup16 needs to know this when KEEP_IT_REAL is used.  There
247
+     * are no harmful side-effects of calculating it all the time.
248
+     */
249
+    _text_load_size_pgh = ( _data_load_addr - _text_load_addr ) / 16 ;
250
+
251
+    /*
252
+     * Useful-to-know values.
253
+     */
254
+
255
+    /* Size of the decompressed runtime image */
256
+    _runtime_size = _edata - _text;
257
+    /* Size of the initialised-contents portion of the runtime image */
258
+    _runtime_progbits_size = _progbits_end - _text;
259
+    /* Size of the (non-compressed) binary file */
260
+    _file_size = _prefix_size + _runtime_progbits_size;
261
+    /* Size of the non-compressed portion of the compressed binary file */
262
+    _zfile_noncompressed_size = _prefix_size + _decompress_size;
263
+}

+ 243
- 0
src/arch/i386/transitions/libkir.S View File

@@ -0,0 +1,243 @@
1
+/*
2
+ * libkir: a transition library for -DKEEP_IT_REAL
3
+ *
4
+ * Michael Brown <mbrown@fensystems.co.uk>
5
+ *
6
+ */
7
+
8
+/****************************************************************************
9
+ * This file defines libkir: an interface between external and
10
+ * internal environments when -DKEEP_IT_REAL is used, so that both
11
+ * internal and external environments are in real mode.  It deals with
12
+ * switching data segments and the stack.  It provides the following
13
+ * functions:
14
+ *
15
+ * ext_to_kir &		switch between external and internal (kir)
16
+ * kir_to_ext		environments, preserving all non-segment
17
+ *			registers
18
+ *
19
+ * kir_call		issue a call to an internal routine from external
20
+ *			code
21
+ *
22
+ * libkir is written to avoid assuming that segments are anything
23
+ * other than opaque data types, and also avoids assuming that the
24
+ * stack pointer is 16-bit.  This should enable it to run just as well
25
+ * in 16:16 or 16:32 protected mode as in real mode.
26
+ ****************************************************************************
27
+ */
28
+
29
+/* Breakpoint for when debugging under bochs */
30
+#define BOCHSBP xchgw %bx, %bx
31
+
32
+	.text
33
+	.arch i386
34
+	.section ".text16", "awx", @progbits
35
+	.code16
36
+	
37
+/****************************************************************************
38
+ * ext_to_kir (real-mode or 16:xx protected-mode near call)
39
+ *
40
+ * Switch from external stack and segment registers to internal stack
41
+ * and segment registers.  %ss:sp is restored from the saved kir_ds
42
+ * and kir_sp.  %ds, %es, %fs and %gs are all restored from the saved
43
+ * kir_ds.  All other registers are preserved.
44
+ *
45
+ * %cs:0000 must point to the start of the runtime image code segment
46
+ * on entry.
47
+ *
48
+ * Note that this routine can be called *without* having first set up
49
+ * a stored kir_ds and kir_sp.  If you do this, ext_to_kir will return
50
+ * without altering the segment registers or stack pointer.
51
+ *
52
+ * Parameters: none
53
+ ****************************************************************************
54
+ */
55
+
56
+	.globl	ext_to_kir
57
+ext_to_kir:
58
+	/* Record external segment registers */
59
+	movw	%ds, %cs:ext_ds
60
+	pushw	%cs
61
+	popw	%ds	/* Set %ds = %cs for easier access to variables */
62
+	movw	%es, %ds:ext_es
63
+	movw	%fs, %ds:ext_fs
64
+	movw	%gs, %ds:ext_fs
65
+
66
+	/* Preserve registers */
67
+	movw	%ax, %ds:save_ax
68
+
69
+	/* Extract near return address from stack */
70
+	popw	%ds:save_retaddr
71
+
72
+	/* Record external %ss:esp */
73
+	movw	%ss, %ds:ext_ss
74
+	movl	%esp, %ds:ext_esp
75
+
76
+	/* Load internal segment registers and stack pointer, if available */
77
+	movw	%ds:kir_ds, %ax
78
+	testw	%ax, %ax
79
+	jz	1f
80
+	movw	%ax, %ss
81
+	movzwl	%ds:kir_sp, %esp
82
+	movw	%ax, %ds
83
+	movw	%ax, %es
84
+	movw	%ax, %fs
85
+	movw	%ax, %gs
86
+1:
87
+
88
+	/* Place return address on new stack */
89
+	pushw	%cs:save_retaddr
90
+	
91
+	/* Restore registers and return */
92
+	movw	%cs:save_ax, %ax
93
+	ret
94
+
95
+/****************************************************************************
96
+ * kir_to_ext (real-mode or 16:xx protected-mode near call)
97
+ *
98
+ * Switch from internal stack and segment registers to external stack
99
+ * and segment registers.  %ss:%esp is restored from the saved ext_ss
100
+ * and ext_esp.  Other segment registers are restored from the
101
+ * corresponding locations.  All other registers are preserved.
102
+ *
103
+ * Note that it is actually %ss that is recorded as kir_ds, on the
104
+ * assumption that %ss == %ds when kir_to_ext is called.
105
+ *
106
+ * Parameters: none
107
+ ****************************************************************************
108
+ */
109
+
110
+	.globl	kir_to_ext
111
+kir_to_ext:
112
+	/* Record near return address */
113
+	pushw	%cs
114
+	popw	%ds	/* Set %ds = %cs for easier access to variables */
115
+	popw	%ds:save_retaddr
116
+	
117
+	/* Record internal segment registers and %sp */
118
+	movw	%ss, %ds:kir_ds
119
+	movw	%sp, %ds:kir_sp
120
+
121
+	/* Load external segment registers and stack pointer */
122
+	movw	%ds:ext_ss, %ss
123
+	movl	%ds:ext_esp, %esp
124
+	movw	%ds:ext_gs, %gs
125
+	movw	%ds:ext_fs, %fs
126
+	movw	%ds:ext_es, %es
127
+	movw	%ds:ext_ds, %ds
128
+
129
+	/* Return */
130
+	pushw	%cs:save_retaddr
131
+	ret
132
+	
133
+/****************************************************************************
134
+ * kir_call (real-mode or 16:xx protected-mode far call)
135
+ *
136
+ * Call a specific C function in the internal code.  The prototype of
137
+ * the C function must be
138
+ *   void function ( struct real_mode_regs *rm_regs ); 
139
+ * rm_regs will point to a struct containing the real-mode registers
140
+ * at entry to kir_call.
141
+ *
142
+ * All registers will be preserved across kir_call(), unless the C
143
+ * function explicitly overwrites values in rm_regs.  Interrupt status
144
+ * will also be preserved.
145
+ *
146
+ * Parameters:
147
+ *   function : (16-bit) virtual address of protected-mode function to call
148
+ *
149
+ * Example usage:
150
+ *	pushw	$pxe_api_call
151
+ *	lcall	$UNDI_CS, $kir_call
152
+ *	addw	$2, %sp
153
+ * to call in to the C function
154
+ *      void pxe_api_call ( struct real_mode_regs *rm_regs );
155
+ ****************************************************************************
156
+ */
157
+
158
+	.globl	kir_call
159
+kir_call:
160
+
161
+	/* Preserve flags.  Must do this before any operation that may
162
+	 * affect flags.
163
+	 */
164
+	pushfl
165
+	popl	%cs:save_flags
166
+
167
+	/* Disable interrupts.  We do funny things with the stack, and
168
+	 * we're not re-entrant.
169
+	 */
170
+	cli
171
+		
172
+	/* Extract address of internal routine from stack.  We must do
173
+	 * this without using (%bp), because we may be called with
174
+	 * either a 16-bit or a 32-bit stack segment.
175
+	 */
176
+	popl	%cs:save_retaddr	/* Scratch location */
177
+	popw	%cs:save_function
178
+	subl	$6, %esp		/* Restore %esp */
179
+	
180
+	/* Switch to internal stack.  Note that the external stack is
181
+	 * inaccessible once we're running internally (since we have
182
+	 * no concept of 48-bit far pointers)
183
+	 */
184
+	call	ext_to_kir
185
+	
186
+	/* Store external registers on internal stack */
187
+	pushl	%cs:save_flags
188
+	pushal
189
+	pushl	%cs:ext_fs_and_gs
190
+	pushl	%cs:ext_ds_and_es
191
+	pushl	%cs:ext_cs_and_ss
192
+
193
+	/* Push &rm_regs on stack and call function */
194
+	pushl	%esp
195
+	data32 call *%cs:save_function
196
+	popl	%eax /* discard */
197
+	
198
+	/* Restore external registers from internal stack */
199
+	popl	%cs:ext_cs_and_ss
200
+	popl	%cs:ext_ds_and_es
201
+	popl	%cs:ext_fs_and_gs
202
+	popal
203
+	popl	%cs:save_flags
204
+
205
+	/* Switch to external stack */
206
+	call	kir_to_ext
207
+
208
+	/* Restore flags */
209
+	pushl	%cs:save_flags
210
+	popfl
211
+
212
+	/* Return */
213
+	lret
214
+
215
+/****************************************************************************
216
+ * Stored internal and external stack and segment registers
217
+ ****************************************************************************
218
+ */
219
+	
220
+ext_cs_and_ss:	
221
+ext_cs:		.word 0
222
+ext_ss:		.word 0
223
+ext_ds_and_es:	
224
+ext_ds:		.word 0
225
+ext_es:		.word 0
226
+ext_fs_and_gs:	
227
+ext_fs:		.word 0
228
+ext_gs:		.word 0
229
+ext_esp:	.long 0
230
+
231
+		.globl kir_ds
232
+kir_ds:		.word 0
233
+		.globl kir_sp
234
+kir_sp:		.word 0
235
+
236
+/****************************************************************************
237
+ * Temporary variables
238
+ ****************************************************************************
239
+ */
240
+save_ax:	.word 0
241
+save_retaddr:	.word 0
242
+save_flags:	.long 0
243
+save_function:	.long 0

+ 0
- 0
src/arch/i386/transitions/libpm.S View File


+ 691
- 0
src/arch/i386/transitions/librm.S View File

@@ -0,0 +1,691 @@
1
+/*
2
+ * librm: a library for interfacing to real-mode code
3
+ *
4
+ * Michael Brown <mbrown@fensystems.co.uk>
5
+ *
6
+ */
7
+
8
+/* Drag in local definitions */
9
+#include "librm.h"
10
+
11
+/****************************************************************************
12
+ * This file defines librm: a block of code that is designed to reside
13
+ * permanently in base memory and provide the interface between
14
+ * real-mode code running in base memory and protected-mode code
15
+ * running in high memory.  It provides the following functions:
16
+ *
17
+ *   real_to_prot &	switch between real and protected mode 
18
+ *   prot_to_real	while running in base memory, preserving 
19
+ *			all non-segment registers
20
+ *
21
+ *   real_call		issue a call to a real-mode routine from
22
+ *			protected-mode code running in high memory
23
+ *
24
+ *   prot_call		issue a call to a protected-mode routine from
25
+ *			real-mode code running in base memory
26
+ *
27
+ * librm requires the following functions to be present in the
28
+ * protected-mode code:
29
+ *
30
+ *   _phys_to_virt	Switch from physical to virtual addressing.  This
31
+ *			routine must be position-independent and must
32
+ *			*not* assume that it is genuinely running with
33
+ *			flat physical addresses
34
+ *
35
+ *   _virt_to_phys	Switch from virtual to physical addresses.
36
+ *
37
+ *   gateA20_set	Enable the A20 line to permit access to the odd
38
+ *			megabytes of RAM.  (This function will be called
39
+ *			with virtual addresses set up).
40
+ *
41
+ * librm needs to be linked against the protected-mode binary so that
42
+ * it can import the symbols for these functions.
43
+ *
44
+ * librm requires that the protected-mode code set up the following
45
+ * segments:
46
+ *
47
+ *   PHYSICAL_CS	32-bit pmode code and data segments with flat
48
+ *   PHYSICAL_DS	physical addresses.
49
+ *
50
+ *   VIRTUAL_CS		32-bit pmode code segment with virtual
51
+ *			addressing, such that a protected-mode routine
52
+ *			can always be found at $VIRTUAL_CS:routine.
53
+ *
54
+ * These segments must be set as #define constants when compiling
55
+ * librm.  Edit librm.h to change the values.
56
+ *
57
+ * librm does not know the location of the code executing in high
58
+ * memory.  It relies on the code running in high memory setting up a
59
+ * GDT such that the high-memory code is accessible at virtual
60
+ * addresses fixed at compile-time.
61
+ *
62
+ * librm symbols are exported as absolute values and represent offsets
63
+ * into librm.  This is the most useful form of the symbols, since
64
+ * librm is basically a binary blob that you place somewhere in base
65
+ * memory.
66
+ *
67
+ * librm.h provides convenient ways to use these symbols: you simply
68
+ * set the pointer ( char * ) installed_librm to point to wherever
69
+ * librm is installed, and can then use e.g. inst_rm_stack just like
70
+ * any other variable and have it automatically refer to the value of
71
+ * rm_stack in the installed librm.  Macro trickery makes this
72
+ * completely transparent, and the resulting assembler code is
73
+ * amazingly efficient.
74
+ *
75
+ * Note that librm must be called in genuine real mode, not 16:16 or
76
+ * 16:32 protected mode.  It makes the assumption that
77
+ * physical_address = 16*segment+offset, and also that it can use
78
+ * OFFSET(%bp) to access stack variables.  The former assumption will
79
+ * break in either protected mode, the latter may break in 16:32
80
+ * protected mode.
81
+ ****************************************************************************
82
+ */
83
+
84
+/*
85
+ * Default values for pmode segments if not defined
86
+ */
87
+#ifndef PHYSICAL_CS
88
+#warning "Assuming PHYSICAL_CS = 0x08"
89
+#define PHYSICAL_CS 0x08
90
+#endif
91
+#ifndef PHYSICAL_DS
92
+#warning "Assuming PHYSICAL_DS = 0x10"
93
+#define PHYSICAL_DS 0x10
94
+#endif
95
+#ifndef VIRTUAL_CS
96
+#warning "Assuming VIRTUAL_CS = 0x18"
97
+#define VIRTUAL_CS 0x18
98
+#endif
99
+
100
+/* For switches to/from protected mode */
101
+#define CR0_PE 1
102
+
103
+/* Size of various C data structures */
104
+#define SIZEOF_I386_SEG_REGS	12
105
+#define SIZEOF_I386_REGS	32
106
+#define SIZEOF_I386_ALL_REGS	( SIZEOF_I386_SEG_REGS + SIZEOF_I386_REGS )
107
+#define SIZEOF_I386_FLAGS	4
108
+#define SIZEOF_REAL_MODE_REGS   ( SIZEOF_I386_ALL_REGS + SIZEOF_I386_FLAGS )
109
+#define SIZEOF_SEGOFF_T		4
110
+#define SIZEOF_REAL_CALL_PARAMS ( SIZEOF_I386_ALL_REGS + 2 * SIZEOF_SEGOFF_T )
111
+	
112
+	.text
113
+	.arch i386
114
+	.section ".librm", "awx", @progbits
115
+	.align 16
116
+
117
+	.globl	librm
118
+librm:
119
+	
120
+_librm_start:
121
+
122
+#undef OFFSET
123
+#define OFFSET(sym) ( sym - _librm_start )
124
+
125
+#undef EXPORT
126
+#define EXPORT(sym) \
127
+	.globl sym ; \
128
+	.globl _ ## sym ;  \
129
+	.equ _ ## sym, OFFSET(sym) ; \
130
+	sym
131
+
132
+/****************************************************************************
133
+ * GDT for initial transition to protected mode
134
+ *
135
+ * PHYSICAL_CS and PHYSICAL_DS are defined in an external header file.
136
+ * We use only those selectors, and construct our GDT to match the
137
+ * selector values we're asked to use.  Use PHYSICAL_CS=0x08 and
138
+ * PHYSICAL_DS=0x10 to minimise the space occupied by this GDT.
139
+ *
140
+ * Note: pm_gdt is also used to store the location of the
141
+ * protected-mode GDT as recorded on entry to prot_to_real.
142
+ ****************************************************************************
143
+ */
144
+	.align 16
145
+pm_gdt:
146
+pm_gdt_limit:		.word pm_gdt_length - 1
147
+pm_gdt_addr:		.long 0
148
+			.word 0 /* padding */
149
+	
150
+	.org	pm_gdt + PHYSICAL_CS
151
+pm_gdt_pm_cs:
152
+	/* 32 bit protected mode code segment, physical addresses */
153
+	.word	0xffff, 0
154
+	.byte	0, 0x9f, 0xcf, 0
155
+	
156
+	.org	pm_gdt + PHYSICAL_DS
157
+pm_gdt_pm_ds:
158
+	/* 32 bit protected mode data segment, physical addresses */
159
+	.word	0xffff,0
160
+	.byte	0,0x93,0xcf,0
161
+	
162
+pm_gdt_end:		
163
+	.equ	pm_gdt_length, pm_gdt_end - pm_gdt
164
+
165
+/****************************************************************************
166
+ * GDT for transition to real mode
167
+ *
168
+ * This is used primarily to set 64kB segment limits.  Define
169
+ * FLATTEN_REAL_MODE if you want to use so-called "flat real mode"
170
+ * with 4GB limits instead.  The base address of each of the segments
171
+ * will be adjusted at run-time.
172
+ *
173
+ * NOTE: This must be located before prot_to_real, otherwise gas
174
+ * throws a "can't handle non absolute segment in `ljmp'" error due to
175
+ * not knowing the value of RM_CS when the ljmp is encountered.
176
+ *
177
+ * Note also that putting ".word rm_gdt_end - rm_gdt - 1" directly
178
+ * into rm_gdt_limit, rather than going via rm_gdt_length, will also
179
+ * produce the "non absolute segment" error.  This is most probably a
180
+ * bug in gas.
181
+ ****************************************************************************
182
+ */
183
+	
184
+#ifdef FLATTEN_REAL_MODE
185
+#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x8f
186
+#else
187
+#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x00
188
+#endif
189
+	.align 16
190
+rm_gdt:
191
+rm_gdt_limit:		.word rm_gdt_length - 1
192
+rm_gdt_base:		.long 0
193
+			.word 0 /* padding */
194
+	
195
+rm_gdt_rm_cs: 	/* 16 bit real mode code segment */
196
+	.equ	RM_CS, rm_gdt_rm_cs - rm_gdt
197
+	.word	0xffff,(0&0xffff)
198
+	.byte	(0>>16),0x9b,RM_LIMIT_16_19__AVL__SIZE__GRANULARITY,(0>>24)
199
+	
200
+rm_gdt_rm_ds:	/* 16 bit real mode data segment */
201
+	.equ	RM_DS, rm_gdt_rm_ds - rm_gdt
202
+	.word	0xffff,(0&0xffff)
203
+	.byte	(0>>16),0x93,RM_LIMIT_16_19__AVL__SIZE__GRANULARITY,(0>>24)
204
+	
205
+rm_gdt_end:
206
+	.equ	rm_gdt_length, rm_gdt_end - rm_gdt
207
+
208
+/****************************************************************************
209
+ * real_to_prot (real-mode far call)
210
+ *
211
+ * Switch from 16-bit real-mode to 32-bit protected mode with flat
212
+ * physical addresses.  %esp is restored from the saved pm_esp.  All
213
+ * segment registers are set to flat physical-mode values.  All other
214
+ * registers are preserved.  Interrupts are disabled.
215
+ *
216
+ * Note that this routine can be called *without* having first set up
217
+ * a stored pm_esp or stored GDT.  If you do this, real_to_prot will
218
+ * return with a temporary stack that is only *FOUR BYTES* in size.
219
+ * This is just enough to enable you to do a "call 1f; popl %ebp"
220
+ * sequence in order to find out your physical address and then load a
221
+ * proper 32-bit protected-mode stack pointer.  Do *NOT* use more than
222
+ * four bytes since this will overwrite code in librm!
223
+ *
224
+ * Parameters: none
225
+ ****************************************************************************
226
+ */
227
+
228
+	.code16		
229
+EXPORT(real_to_prot):
230
+	/* Disable interrupts */
231
+	cli
232
+
233
+	/* Set %ds = %cs, for easier access to variables */
234
+	pushw	%cs
235
+	popw	%ds
236
+	
237
+	/* Preserve registers */
238
+	movl	%eax, %ds:OFFSET(save_eax)
239
+	movl	%ebx, %ds:OFFSET(save_ebx)
240
+
241
+	/* Extract real-mode far return address from stack */
242
+	popl	%ds:OFFSET(save_retaddr)
243
+
244
+	/* Record real-mode stack pointer */
245
+	movw	%sp, %ds:OFFSET(rm_sp)
246
+	pushw	%ss
247
+	popw	%ds:OFFSET(rm_ss)
248
+
249
+	/* Physical base address of librm to %ebx */
250
+	xorl	%ebx, %ebx
251
+	movw	%cs, %bx
252
+	shll	$4, %ebx
253
+		
254
+	/* Check base address of stored protected-mode GDT.  If it's
255
+	 * zero, set it up to use our internal GDT (with physical
256
+	 * segments only).
257
+	 */
258
+	movl	%ds:OFFSET(pm_gdt_addr), %eax
259
+	testl	%eax, %eax
260
+	jnz	1f
261
+	/* Use internal GDT */
262
+	movl	%ebx, %eax
263
+	addl	$OFFSET(pm_gdt), %eax
264
+	movl	%eax, %ds:OFFSET(pm_gdt_addr)
265
+1:	
266
+	
267
+	/* Set up protected-mode continuation address on real-mode stack */
268
+	pushl	$PHYSICAL_CS
269
+	movl	%ebx, %eax
270
+	addl	$OFFSET(1f), %eax
271
+	pushl	%eax
272
+	
273
+	/* Restore protected-mode GDT */
274
+	lgdt	%ds:OFFSET(pm_gdt)
275
+
276
+	/* Switch to protected mode */
277
+	movl	%cr0, %eax
278
+	orb	$CR0_PE, %al
279
+	movl	%eax, %cr0
280
+
281
+	/* Flush prefetch queue and reload %cs:eip */
282
+	data32 lret
283
+1:	.code32
284
+
285
+	/* Set up protected-mode stack and data segments */
286
+	movw	$PHYSICAL_DS, %ax
287
+	movw	%ax, %ds
288
+	movw	%ax, %es
289
+	movw	%ax, %fs
290
+	movw	%ax, %gs
291
+	movw	%ax, %ss
292
+
293
+	/* Switch to saved protected-mode stack.  Note that there may
294
+	 * not actually *be* a saved protected-mode stack.
295
+	 */
296
+	movl	OFFSET(pm_esp)(%ebx), %esp
297
+	testl	%esp, %esp
298
+	jnz	1f
299
+	/* No stack - use save_retaddr as a 4-byte temporary stack */
300
+	leal	OFFSET(save_retaddr+4)(%ebx), %esp
301
+1:	
302
+	
303
+	/* Convert real-mode far return address to physical address
304
+	 * and place on stack
305
+	 */
306
+	pushl	OFFSET(save_retaddr)(%ebx)
307
+	xorl	%eax, %eax
308
+	xchgw	2(%esp), %ax
309
+	shll	$4, %eax
310
+	addl	%eax, 0(%esp)
311
+
312
+	/* Restore registers and return */
313
+	movl	OFFSET(save_eax)(%ebx), %eax
314
+	movl	OFFSET(save_ebx)(%ebx), %ebx
315
+	ret
316
+
317
+/****************************************************************************
318
+ * prot_to_real (protected-mode near call, physical addresses)
319
+ *
320
+ * Switch from 32-bit protected mode with flat physical addresses to
321
+ * 16-bit real mode.  %ss:sp is restored from the saved rm_ss and
322
+ * rm_sp.  %cs is set such that %cs:0000 is the start of librm.  All
323
+ * other segment registers are set to %ss.  All other registers are
324
+ * preserved.  Interrupts are *not* enabled, since we want to be able
325
+ * to use this routine inside an ISR.
326
+ *
327
+ * Note that since %cs:0000 points to the start of librm on exit, it
328
+ * follows that the code calling prot_to_real must be located within
329
+ * 64kB of the start of librm.
330
+ *
331
+ * Parameters: none
332
+ ****************************************************************************
333
+ */
334
+
335
+	.code32
336
+EXPORT(prot_to_real):
337
+	/* Calculate physical base address of librm in %ebx, preserve
338
+	 * original %eax and %ebx in save_eax and save_ebx
339
+	 */
340
+	pushl	%ebx
341
+	call	1f
342
+1:	popl	%ebx
343
+	subl	$OFFSET(1b), %ebx
344
+	popl	OFFSET(save_ebx)(%ebx)
345
+	movl	%eax, OFFSET(save_eax)(%ebx)
346
+
347
+	/* Extract return address from the stack, convert to offset
348
+	 * within librm and save in save_retaddr
349
+	 */
350
+	popl	%eax
351
+	subl	%ebx, %eax
352
+	movl	%eax, OFFSET(save_retaddr)(%ebx)
353
+
354
+	/* Record protected-mode stack pointer */
355
+	movl	%esp, OFFSET(pm_esp)(%ebx)
356
+
357
+	/* Record protected-mode GDT */
358
+	sgdt	OFFSET(pm_gdt)(%ebx)
359
+
360
+	/* Set up real-mode GDT */
361
+	leal	OFFSET(rm_gdt)(%ebx), %eax
362
+	movl	%eax, OFFSET(rm_gdt_base)(%ebx)
363
+	movl	%ebx, %eax
364
+	rorl	$16, %eax
365
+	movw	%bx, OFFSET(rm_gdt_rm_cs+2)(%ebx)
366
+	movb	%al, OFFSET(rm_gdt_rm_cs+4)(%ebx)
367
+	movw	%bx, OFFSET(rm_gdt_rm_ds+2)(%ebx)
368
+	movb	%al, OFFSET(rm_gdt_rm_ds+4)(%ebx)
369
+	
370
+	/* Switch to real-mode GDT and reload segment registers to get
371
+	 * 64kB limits.  Stack is invalidated by this process.
372
+	 */
373
+	lgdt	OFFSET(rm_gdt)(%ebx)
374
+	ljmp	$RM_CS, $1f
375
+1:	.code16
376
+	movw	$RM_DS, %ax
377
+	movw	%ax, %ds
378
+	movw	%ax, %es
379
+	movw	%ax, %fs
380
+	movw	%ax, %gs
381
+	movw	%ax, %ss
382
+
383
+	/* Calculate real-mode code segment in %ax and store in ljmp
384
+	 * instruction
385
+	 */
386
+	movl	%ebx, %eax
387
+	shrl	$4, %eax
388
+	movw	%ax, OFFSET(p2r_ljmp) + 3
389
+
390
+	/* Switch to real mode */
391
+	movl	%cr0, %ebx
392
+	andb	$0!CR0_PE, %bl
393
+	movl	%ebx, %cr0
394
+
395
+	/* Intersegment jump to flush prefetch queue and reload
396
+	 * %cs:eip.  The segment gets filled in by the above code.  We
397
+	 * can't just use lret to achieve this, because we have no
398
+	 * stack at the moment.
399
+	 */
400
+p2r_ljmp:
401
+	ljmp	$0, $OFFSET(1f)
402
+1:	
403
+
404
+	/* Set %ds to point to code segment for easier data access */
405
+	movw	%ax, %ds
406
+			
407
+	/* Restore registers */
408
+	movl	OFFSET(save_eax), %eax
409
+	movl	OFFSET(save_ebx), %ebx
410
+
411
+	/* Set up real-mode data segments and stack */
412
+	movw	OFFSET(rm_ss), %ss
413
+	movw	OFFSET(rm_sp), %sp
414
+	pushw	%ss
415
+	pushw	%ss
416
+	pushw	%ss
417
+	pushw	%ss
418
+	popw	%ds
419
+	popw	%es
420
+	popw	%fs
421
+	popw	%gs
422
+
423
+	/* Set up return address on stack and return */
424
+	pushw	%cs:OFFSET(save_retaddr)
425
+	ret
426
+
427
+/****************************************************************************
428
+ * prot_call (real-mode far call)
429
+ *
430
+ * Call a specific C function in the protected-mode code.  The
431
+ * prototype of the C function must be
432
+ *   void function ( struct real_mode_regs *rm_regs,
433
+ *		     void (*retaddr) (void) ); 
434
+ * rm_regs will point to a struct containing the real-mode registers
435
+ * at entry to prot_call.  retaddr will point to the (virtual) return
436
+ * address from "function".  This return address will point into
437
+ * librm.  It is included so that "function" may, if desired, relocate
438
+ * librm and return via the new copy.  It must not be directly called
439
+ * as a function, i.e. you may not do "*retaddr()"; you must instead
440
+ * do something like:
441
+ *	*retaddr += ( new_librm_location - old_librm_location );
442
+ *	return;
443
+ *
444
+ * All registers will be preserved across prot_call(), unless the C
445
+ * function explicitly overwrites values in rm_regs.  Interrupt status
446
+ * will also be preserved.  Gate A20 will be enabled.
447
+ *
448
+ * Parameters:
449
+ *   function : virtual address of protected-mode function to call
450
+ *
451
+ * Example usage:
452
+ *	pushl	$pxe_api_call
453
+ *	lcall	$LIBRM_SEGMENT, $prot_call
454
+ *	addw	$4, %sp
455
+ * to call in to the C function
456
+ *      void pxe_api_call ( struct real_mode_regs *rm_regs );
457
+ ****************************************************************************
458
+ */
459
+
460
+#define PC_OFFSET_RM_REGS ( 0 )
461
+#define PC_OFFSET_RETADDR ( PC_OFFSET_RM_REGS + SIZEOF_REAL_MODE_REGS )
462
+#define PC_OFFSET_FUNCTION ( PC_OFFSET_RETADDR + 4 )
463
+	
464
+	.code16
465
+EXPORT(prot_call):
466
+	/* Preserve registers and flags on RM stack */
467
+	pushfl
468
+	pushal
469
+	pushw	%gs
470
+	pushw	%fs
471
+	pushw	%es
472
+	pushw	%ds
473
+	pushw	%ss
474
+	pushw	%cs	
475
+	
476
+	/* Record RM stack pointer */
477
+	xorl	%ebp, %ebp
478
+	movw	%sp, %bp
479
+	
480
+	/* Physical address of RM stack pointer to %esi */
481
+	xorl	%esi, %esi
482
+	pushw	%ss
483
+	popw	%si
484
+	shll	$4, %esi
485
+	addl	%ebp, %esi
486
+
487
+	/* Address of pmode function to %ebx */
488
+	movl	%ss:(PC_OFFSET_FUNCTION)(%bp), %ebx
489
+	
490
+	/* Switch to protected mode */
491
+	pushw	%cs
492
+	call	real_to_prot
493
+	.code32
494
+
495
+	/* Copy rm_regs from RM stack to PM stack */
496
+	movl	$SIZEOF_REAL_MODE_REGS, %ecx
497
+	subl	%ecx, %esp
498
+	movl	%esp, %edi
499
+	cld
500
+	rep	movsb
501
+	
502
+	/* Switch to virtual addresses. */
503
+	call	1f
504
+	jmp	2f
505
+1:	ljmp	$VIRTUAL_CS, $_phys_to_virt
506
+2:	
507
+
508
+	/* Enable A20 line */
509
+	pushal
510
+	lcall	$VIRTUAL_CS, $gateA20_set
511
+	popl	%eax	/* discard */
512
+	popal
513
+
514
+	/* Push &rm_regs and &retaddr on the stack, and call function */
515
+	movl	%esp, %ebp
516
+	pushl	%esp
517
+	subl	$12, 0(%esp)
518
+	pushl	%ebp
519
+	call	*%ebx
520
+	popl	%eax /* discard */
521
+	popl	%eax /* discard */
522
+
523
+	/* Switch to physical addresses, discard PM register store */
524
+	lcall	$VIRTUAL_CS, $_virt_to_phys
525
+	addl	$SIZEOF_REAL_MODE_REGS+4, %esp /* also discard lcall seg */
526
+
527
+	/* Switch to real mode */
528
+	call	prot_to_real
529
+	.code16
530
+
531
+	/* Restore registers and flags, and return */
532
+	popw	%ax	/* skip %cs */
533
+	popw	%ax	/* skip %ss */
534
+	popw	%ds
535
+	popw	%es
536
+	popw	%fs
537
+	popw	%gs
538
+	popal
539
+	popfl
540
+	lret
541
+
542
+/****************************************************************************
543
+ * real_call (protected-mode near call, virtual addresses)
544
+ *
545
+ * Call a real-mode function from protected-mode code.
546
+ *
547
+ * The non-segment register values will be passed directly to the
548
+ * real-mode code.  The segment registers will be set as per
549
+ * prot_to_real.  The non-segment register values set by the real-mode
550
+ * function will be passed back to the protected-mode caller.  A
551
+ * result of this is that this routine cannot be called directly from
552
+ * C code, since it clobbers registers that the C ABI expects the
553
+ * callee to preserve.  Gate A20 will be re-enabled in case the
554
+ * real-mode routine disabled it.
555
+ *
556
+ * librm.h defines two convenient macros for using real_call:
557
+ * REAL_CALL and REAL_EXEC.  See librm.h and realmode.h for details
558
+ * and examples.
559
+ *
560
+ * Parameters:
561
+ *   far pointer to real-mode function to call
562
+ *
563
+ * Returns: none
564
+ ****************************************************************************
565
+ */
566
+
567
+#define RC_OFFSET_PRESERVE_REGS ( 0 )
568
+#define RC_OFFSET_RETADDR ( RC_OFFSET_PRESERVE_REGS + 8 )
569
+#define RC_OFFSET_RM_FUNCTION ( RC_OFFSET_RETADDR + 4 )
570
+	
571
+	.code32
572
+EXPORT(real_call):
573
+	/* Preserve registers */
574
+	pushl	%ebp
575
+	pushl	%eax
576
+	
577
+	/* Switch to physical addresses */
578
+	lcall	$VIRTUAL_CS, $_virt_to_phys
579
+	addl	$4, %esp
580
+
581
+	/* Extract real-mode function address and store in ljmp instruction */
582
+	call	1f
583
+1:	popl	%ebp
584
+	movl	RC_OFFSET_RM_FUNCTION(%esp), %eax
585
+	movl	%eax, (rc_ljmp + 1 - 1b)(%ebp)
586
+
587
+	/* Restore registers */
588
+	popl	%eax
589
+	popl	%ebp
590
+
591
+	/* Switch to real mode, preserving non-segment registers */
592
+	call	prot_to_real
593
+	.code16
594
+
595
+	/* Far call to real-mode routine */
596
+	pushw	%cs
597
+	call	rc_ljmp
598
+	jmp	2f
599
+rc_ljmp:	
600
+	ljmp	$0, $0	/* address filled in by above code */
601
+2:	
602
+	
603
+	/* Switch to protected mode */
604
+	pushw	%cs
605
+	call	real_to_prot
606
+	.code32
607
+
608
+	/* Switch to virtual addresses */
609
+	call	1f
610
+	jmp	2f
611
+1:	ljmp	$VIRTUAL_CS, $_phys_to_virt
612
+2:	
613
+
614
+	/* Enable A20 line */
615
+	pushal
616
+	lcall	$VIRTUAL_CS, $gateA20_set
617
+	popl	%eax	/* discard */
618
+	popal
619
+
620
+	/* Return */
621
+	ret
622
+	
623
+/****************************************************************************
624
+ * Relocation lock counter
625
+ *
626
+ * librm may be moved in base memory only when this counter is zero.
627
+ * The counter gets incremented whenever a reference to librm is
628
+ * generated (e.g. a real_call is made, resulting in a return address
629
+ * pointing to librm being placed on the stack), and decremented when
630
+ * the reference goes out of scope (e.g. the real_call returns).
631
+ ****************************************************************************
632
+ */
633
+EXPORT(librm_ref_count):	.byte 0
634
+
635
+/****************************************************************************
636
+ * Stored real-mode and protected-mode stack pointers
637
+ *
638
+ * The real-mode stack pointer is stored here whenever real_to_prot
639
+ * is called and restored whenever prot_to_real is called.  The
640
+ * converse happens for the protected-mode stack pointer.
641
+ *
642
+ * Despite initial appearances this scheme is, in fact re-entrant,
643
+ * because program flow dictates that we always return via the point
644
+ * we left by.  For example:
645
+ *    PXE API call entry
646
+ *  1   real => prot
647
+ *        ...
648
+ *        Print a text string
649
+ *	    ...
650
+ *  2       prot => real
651
+ *            INT 10
652
+ *  3       real => prot
653
+ *	    ...
654
+ *        ...
655
+ *  4   prot => real
656
+ *    PXE API call exit
657
+ *
658
+ * At point 1, the RM mode stack value, say RPXE, is stored in
659
+ * rm_ss,sp.  We want this value to still be present in rm_ss,sp when
660
+ * we reach point 4.
661
+ *
662
+ * At point 2, the RM stack value is restored from RPXE.  At point 3,
663
+ * the RM stack value is again stored in rm_ss,sp.  This *does*
664
+ * overwrite the RPXE that we have stored there, but it's the same
665
+ * value, since the code between points 2 and 3 has managed to return
666
+ * to us.
667
+ ****************************************************************************
668
+ */
669
+
670
+EXPORT(rm_stack):	/* comprises rm_ss and rm_sp */
671
+rm_sp:		.word 0
672
+rm_ss:		.word 0
673
+
674
+EXPORT(pm_stack):
675
+pm_esp:		.long 0
676
+
677
+/****************************************************************************
678
+ * Temporary variables
679
+ ****************************************************************************
680
+ */
681
+save_eax:	.long 0
682
+save_ebx:	.long 0
683
+save_retaddr:	.long 0
684
+	
685
+/****************************************************************************
686
+ * End of librm
687
+ ****************************************************************************
688
+ */
689
+_librm_end:
690
+	.globl _librm_size
691
+	.equ _librm_size, _librm_end - _librm_start

+ 87
- 0
src/arch/i386/transitions/librm_mgmt.c View File

@@ -0,0 +1,87 @@
1
+/*
2
+ * librm: a library for interfacing to real-mode code
3
+ *
4
+ * Michael Brown <mbrown@fensystems.co.uk>
5
+ *
6
+ */
7
+
8
+#ifdef KEEP_IT_REAL
9
+/* Build a null object under -DKEEP_IT_REAL */
10
+#else
11
+
12
+#include "stdint.h"
13
+#include "stddef.h"
14
+#include "string.h"
15
+#include "librm.h"
16
+
17
+/*
18
+ * This file provides functions for managing librm.
19
+ *
20
+ */
21
+
22
+/* Current location of librm in base memory */
23
+char *installed_librm = librm;
24
+
25
+/*
26
+ * Install librm to base memory
27
+ *
28
+ */
29
+void install_librm ( void *addr ) {
30
+	memcpy ( addr, librm, librm_size );
31
+	installed_librm = addr;
32
+}
33
+
34
+/*
35
+ * Increment lock count of librm
36
+ *
37
+ */
38
+void lock_librm ( void ) {
39
+	inst_librm_ref_count++;
40
+}
41
+
42
+/*
43
+ * Decrement lock count of librm
44
+ *
45
+ */
46
+void unlock_librm ( void ) {
47
+#ifdef DEBUG_LIBRM
48
+	if ( inst_librm_ref_count == 0 ) {
49
+		printf ( "librm: ref count gone negative\n" );
50
+		lockup();
51
+	}
52
+#endif
53
+	inst_librm_ref_count--;
54
+}
55
+
56
+/*
57
+ * Allocate space on the real-mode stack and copy data there.
58
+ *
59
+ */
60
+uint16_t copy_to_rm_stack ( void *data, size_t size ) {
61
+#ifdef DEBUG_LIBRM
62
+	if ( inst_rm_stack.offset <= size ) {
63
+		printf ( "librm: out of space in RM stack\n" );
64
+		lockup();
65
+	}
66
+#endif
67
+	inst_rm_stack.offset -= size;
68
+	copy_to_real ( inst_rm_stack.segment, inst_rm_stack.offset,
69
+		       data, size );
70
+	return inst_rm_stack.offset;
71
+};
72
+
73
+/*
74
+ * Deallocate space on the real-mode stack, optionally copying back
75
+ * data.
76
+ *
77
+ */
78
+void remove_from_rm_stack ( void *data, size_t size ) {
79
+	if ( data ) {
80
+		copy_from_real ( data,
81
+				 inst_rm_stack.segment, inst_rm_stack.offset,
82
+				 size );
83
+	}
84
+	inst_rm_stack.offset += size;
85
+};
86
+
87
+#endif /* KEEP_IT_REAL */

+ 4
- 1
src/arch/ia64/core/ia64_timer.c View File

@@ -2,6 +2,7 @@
2 2
 #include "timer.h"
3 3
 #include "sal.h"
4 4
 #include "pal.h"
5
+#include "init.h"
5 6
 
6 7
 static inline unsigned long get_cycles(void)
7 8
 {
@@ -39,7 +40,7 @@ static unsigned long calibrate_cycles(void)
39 40
 }
40 41
 
41 42
 static unsigned long clocks_per_tick;
42
-void setup_timers(void)
43
+static void setup_timers(void)
43 44
 {
44 45
 	if (!clocks_per_tick) {
45 46
 		clocks_per_tick = calibrate_cycles();
@@ -87,3 +88,5 @@ int timer2_running(void)
87 88
 {
88 89
 	return __timer_running();
89 90
 }
91
+
92
+INIT_FN ( INIT_TIMERS, setup_timers, NULL, NULL );

+ 1
- 0
src/bin/.cvsignore View File

@@ -0,0 +1 @@
1
+*

+ 30
- 28
src/core/btext.c View File

@@ -1,5 +1,3 @@
1
-#ifdef CONSOLE_BTEXT
2
-#ifdef CONFIG_PCI
3 1
 /*
4 2
  * Procedures for drawing on the screen early on in the boot process.
5 3
  *
@@ -10,6 +8,8 @@
10 8
  */
11 9
 
12 10
 #include "etherboot.h"
11
+#include "console.h"
12
+#include "init.h"
13 13
 #include "pci.h"
14 14
 
15 15
 #ifdef CONFIG_FILO
@@ -36,6 +36,8 @@ static void draw_byte_16(unsigned char *bits, u32 *base, u32 rb);
36 36
 #endif
37 37
 static void draw_byte_8(unsigned char *bits, u32 *base, u32 rb);
38 38
 
39
+static int pci_find_device_x(int vendorx, int devicex, int index, struct pci_device *dev);
40
+
39 41
 static u32 g_loc_X;
40 42
 static u32 g_loc_Y;
41 43
 static u32 g_max_loc_X;
@@ -62,7 +64,7 @@ boot_infos_t disp_bi;
62 64
 /* This function will enable the early boot text when doing OF booting. This
63 65
  * way, xmon output should work too
64 66
  */
65
-void
67
+static void
66 68
 btext_setup_display(u32 width, u32 height, u32 depth, u32 pitch,
67 69
 		    unsigned long address)
68 70
 {
@@ -73,7 +75,7 @@ btext_setup_display(u32 width, u32 height, u32 depth, u32 pitch,
73 75
 	g_max_loc_X = width / 8;
74 76
 	g_max_loc_Y = height / 16;
75 77
 //	bi->logicalDisplayBase = (unsigned char *)address;
76
-	bi->dispDeviceBase = (unsigned char *)address;
78
+	bi->dispDeviceBase = address;
77 79
 	bi->dispDeviceRowBytes = pitch;
78 80
 	bi->dispDeviceDepth = depth;
79 81
 	bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
@@ -93,7 +95,7 @@ btext_setup_display(u32 width, u32 height, u32 depth, u32 pitch,
93 95
  *    changes.
94 96
  */
95 97
 
96
-void 
98
+static void 
97 99
 map_boot_text(void)
98 100
 {
99 101
 	boot_infos_t *bi = &disp_bi;
@@ -113,18 +115,19 @@ static unsigned char * BTEXT
113 115
 calc_base(boot_infos_t *bi, u32 x, u32 y)
114 116
 {
115 117
 	unsigned char *base;
116
-#if 1
117 118
 	base = bi->logicalDisplayBase;
119
+#if 0
120
+	/* Ummm... which moron wrote this? */
118 121
 	if (base == 0)
119
-#endif
120 122
 		base = bi->dispDeviceBase;
123
+#endif
121 124
 	base += (x + bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3);
122 125
 	base += (y + bi->dispDeviceRect[1]) * bi->dispDeviceRowBytes;
123 126
 	return base;
124 127
 }
125 128
 
126 129
 
127
-void BTEXT btext_clearscreen(void)
130
+static void BTEXT btext_clearscreen(void)
128 131
 {
129 132
 	boot_infos_t* bi	= &disp_bi;
130 133
 	u32 *base	= (u32 *)calc_base(bi, 0, 0);
@@ -147,7 +150,7 @@ __inline__ void dcbst(const void* addr)
147 150
 	__asm__ __volatile__ ("dcbst 0,%0" :: "r" (addr));
148 151
 }
149 152
 
150
-void BTEXT btext_flushscreen(void)
153
+static void BTEXT btext_flushscreen(void)
151 154
 {
152 155
 	boot_infos_t* bi	= &disp_bi;
153 156
 	u32  *base	= (unsigned long *)calc_base(bi, 0, 0);
@@ -198,7 +201,7 @@ scrollscreen(void)
198 201
 }
199 202
 #endif /* ndef NO_SCROLL */
200 203
 
201
-void BTEXT btext_drawchar(char c)
204
+static void BTEXT btext_drawchar(char c)
202 205
 {
203 206
 	u32 cline = 0;
204 207
 
@@ -246,7 +249,7 @@ void BTEXT btext_drawchar(char c)
246 249
 #endif
247 250
 }
248 251
 #if 0
249
-void BTEXT
252
+static void BTEXT
250 253
 btext_drawstring(const char *c)
251 254
 {
252 255
 	if (!boot_text_mapped)
@@ -254,7 +257,7 @@ btext_drawstring(const char *c)
254 257
 	while (*c)
255 258
 		btext_drawchar(*c++);
256 259
 }
257
-void BTEXT
260
+static void BTEXT
258 261
 btext_drawhex(u32 v)
259 262
 {
260 263
 	static char hex_table[] = "0123456789abcdef";
@@ -394,7 +397,7 @@ draw_byte_8(unsigned char *font, u32 *base, u32 rb)
394 397
 #endif
395 398
 
396 399
 
397
-void btext_init(void)
400
+static void btext_init(void)
398 401
 {
399 402
 #if 0
400 403
 // for debug
@@ -402,14 +405,16 @@ void btext_init(void)
402 405
 #else
403 406
     uint32_t frame_buffer;//  0xfc000000
404 407
 
405
-    struct pci_device *dev = 0;
406
-
407 408
 #if USE_FILO_PCI_FIND==0
409
+    struct pci_device dev;
410
+
408 411
     pci_find_device_x(0x1002, 0x4752, 0, &dev);
409 412
     if(dev.vendor==0) return; // no fb
410 413
 
411 414
     frame_buffer = (uint32_t)dev.membase;
412 415
 #else
416
+    struct pci_device *dev = 0;
417
+
413 418
     pci_init();
414 419
     dev = pci_find_device(0x1002, 0x4752, -1, -1, 0);
415 420
     if(!dev) {
@@ -422,21 +427,21 @@ void btext_init(void)
422 427
 #endif
423 428
 
424 429
 	btext_setup_display(640, 480, 8, 640,frame_buffer);
425
-//	btext_clearscreen(); //move to main
426
-//	map_boot_text();  //move console_init
430
+	btext_clearscreen();
431
+	map_boot_text();
427 432
 }
428
-void btext_putc(int c)
433
+static void btext_putc(int c)
429 434
 {	
430 435
         btext_drawchar((unsigned char)c);
431 436
 }
432
-#if 0
433
-static struct console_driver btext_console __console = {
434
-        .init    = btext_init,
435
-        .tx_byte = btext_tx_byte,
436
-        .rx_byte = 0,
437
-        .tst_byte = 0,
437
+
438
+static struct console_driver btext_console __console_driver = {
439
+	.putchar = btext_putc,
440
+	.disabled = 1,
438 441
 };
439
-#endif
442
+
443
+INIT_FN ( INIT_CONSOLE, btext_init, NULL, NULL );
444
+
440 445
 #if USE_FILO_PCI_FIND==0
441 446
 int pci_find_device_x(int vendorx, int devicex, int index, struct pci_device *dev)
442 447
 {                       
@@ -445,7 +450,6 @@ int pci_find_device_x(int vendorx, int devicex, int index, struct pci_device *de
445 450
 #if 1
446 451
         unsigned char hdr_type = 0;
447 452
 #endif
448
-        uint32_t class; 
449 453
         uint16_t vendor, device;
450 454
         uint32_t l, membase;
451 455
 #if 0
@@ -5192,5 +5196,3 @@ static unsigned char vga_font[cmapsz] BTDATA = {
5192 5196
 	0x00, /* 00000000 */
5193 5197
 #endif
5194 5198
 };
5195
-#endif
5196
-#endif

+ 49
- 0
src/core/config.c View File

@@ -7,6 +7,7 @@
7 7
 
8 8
 #include	"etherboot.h"
9 9
 #include	"nic.h"
10
+#include	"console.h"
10 11
 #ifdef BUILD_SERIAL
11 12
 #include	".buildserial.h"
12 13
 #define xstr(s) str(s)
@@ -104,6 +105,9 @@ void print_config(void)
104 105
 		"DNS "
105 106
 #endif
106 107
 		"\n");
108
+#ifdef KEEP_IT_REAL
109
+	printf( "Keeping It Real [EXPERIMENTAL]\n" );
110
+#endif
107 111
 }
108 112
 
109 113
 static const char *driver_name[] = {
@@ -159,3 +163,48 @@ void disable(struct dev *dev)
159 163
 		dev->disable = 0;
160 164
 	}
161 165
 }
166
+
167
+
168
+/*
169
+ * Drag in all requested console types
170
+ *
171
+ * At least one of the CONSOLE_xxx has to be set.  CONSOLE_DUAL sets
172
+ * both CONSOLE_FIRMWARE and CONSOLE_SERIAL for legacy compatibility.
173
+ * If no CONSOLE_xxx is set, CONSOLE_FIRMWARE is assumed.
174
+ */
175
+
176
+#ifdef CONSOLE_CRT
177
+#define CONSOLE_FIRMWARE
178
+#endif
179
+
180
+#ifdef	CONSOLE_DUAL
181
+#undef CONSOLE_FIRMWARE
182
+#define CONSOLE_FIRMWARE
183
+#undef CONSOLE_SERIAL
184
+#define CONSOLE_SERIAL
185
+#endif
186
+
187
+#if	!defined(CONSOLE_FIRMWARE) && !defined(CONSOLE_SERIAL)
188
+#define CONSOLE_FIRMWARE
189
+#endif
190
+
191
+#ifdef CONSOLE_FIRMWARE
192
+REQUIRE_OBJECT ( bios_console );
193
+#endif
194
+
195
+#ifdef CONSOLE_SERIAL
196
+REQUIRE_OBJECT ( serial );
197
+#endif
198
+
199
+#ifdef CONSOLE_DIRECT_VGA
200
+REQUIRE_OBJECT ( video_subr );
201
+#endif
202
+
203
+#ifdef CONSOLE_BTEXT
204
+REQUIRE_OBJECT ( btext );
205
+#endif
206
+
207
+#ifdef CONSOLE_PC_KBD
208
+REQUIRE_OBJECT ( pc_kbd );
209
+#endif
210
+

+ 102
- 0
src/core/console.c View File

@@ -0,0 +1,102 @@
1
+/*
2
+ * Central console switch.  Various console devices can be selected
3
+ * via the build options CONSOLE_FIRMWARE, CONSOLE_SERIAL etc.
4
+ * config.c picks up on these definitions and drags in the relevant
5
+ * objects.  The linker compiles the console_drivers table for us; we
6
+ * simply delegate to each console_driver that we find in the table.
7
+ *
8
+ * Doing it this way allows for changing CONSOLE_XXX without
9
+ * rebuilding anything other than config.o.  This is extremely useful
10
+ * for rom-o-matic.
11
+ */
12
+
13
+#include "stddef.h"
14
+#include "console.h"
15
+
16
+/* FIXME: we need a cleaner way to pick up cpu_nap().  It makes a
17
+ * real-mode call, and so we don't want to use it with LinuxBIOS.
18
+ */
19
+#include "bios.h"
20
+
21
+extern struct console_driver console_drivers[];
22
+extern struct console_driver console_drivers_end[];
23
+
24
+/*****************************************************************************
25
+ * putchar : write a single character to each console
26
+ *****************************************************************************
27
+ */
28
+
29
+void putchar ( int character ) {
30
+	struct console_driver *console;
31
+
32
+	/* Automatic LF -> CR,LF translation */
33
+	if ( character == '\n' )
34
+		putchar ( '\r' );
35
+
36
+	for ( console = console_drivers; console < console_drivers_end ;
37
+	      console++ ) {
38
+		if ( ( ! console->disabled ) && console->putchar )
39
+			console->putchar ( character );
40
+	}
41
+}
42
+
43
+/*****************************************************************************
44
+ * has_input : check to see if any input is available on any console,
45
+ * and return a pointer to the console device if so
46
+ *****************************************************************************
47
+ */
48
+static struct console_driver * has_input ( void ) {
49
+	struct console_driver *console;
50
+
51
+	for ( console = console_drivers; console < console_drivers_end ;
52
+	      console++ ) {
53
+		if ( ( ! console->disabled ) && console->iskey ) {
54
+			if ( console->iskey () )
55
+				return console;
56
+		}
57
+	}
58
+	return NULL;
59
+}
60
+
61
+/*****************************************************************************
62
+ * getchar : read a single character from any console
63
+ *
64
+ * NOTE : this function does not echo the character, and it does block
65
+ *****************************************************************************
66
+ */
67
+
68
+int getchar ( void ) {
69
+	struct console_driver *console;
70
+	int character = 256;
71
+
72
+	while ( character == 256 ) {
73
+		/* Doze for a while (until the next interrupt).  This works
74
+		 * fine, because the keyboard is interrupt-driven, and the
75
+		 * timer interrupt (approx. every 50msec) takes care of the
76
+		 * serial port, which is read by polling.  This reduces the
77
+		 * power dissipation of a modern CPU considerably, and also
78
+		 * makes Etherboot waiting for user interaction waste a lot
79
+		 * less CPU time in a VMware session.
80
+		 */
81
+		cpu_nap();
82
+		
83
+		console = has_input();
84
+		if ( console && console->getchar )
85
+			character = console->getchar ();
86
+	}
87
+
88
+	/* CR -> LF translation */
89
+	if ( character == '\r' )
90
+		character = '\n';
91
+
92
+	return character;
93
+}
94
+
95
+/*****************************************************************************
96
+ * iskey : check to see if any input is available on any console
97
+ *****************************************************************************
98
+ */
99
+
100
+int iskey ( void ) {
101
+	return has_input() ? 1 : 0;
102
+}

+ 12
- 1
src/core/heap.c View File

@@ -1,8 +1,12 @@
1 1
 #include "etherboot.h"
2
+#include "init.h"
3
+#include "memsizes.h"
2 4
 
3 5
 size_t heap_ptr, heap_top, heap_bot;
4 6
 
5
-void init_heap(void)
7
+#define _virt_start 0
8
+
9
+static void init_heap(void)
6 10
 {
7 11
 	size_t size;
8 12
 	size_t start, end;
@@ -82,6 +86,11 @@ void init_heap(void)
82 86
 	heap_ptr = heap_bot;
83 87
 }
84 88
 
89
+static void reset_heap(void)
90
+{
91
+	heap_ptr = heap_bot;
92
+}
93
+
85 94
 void *allot(size_t size)
86 95
 {
87 96
 	void *ptr;
@@ -166,3 +175,5 @@ void forget2(void *ptr)
166 175
         }
167 176
         heap_ptr = addr;
168 177
 }
178
+
179
+INIT_FN ( INIT_HEAP, init_heap, reset_heap, NULL );

+ 44
- 0
src/core/init.c View File

@@ -0,0 +1,44 @@
1
+/**************************************************************************
2
+ * call_{init,reset,exit}_fns ()
3
+ * 
4
+ * Call the various initialisation and exit functions.  We use a
5
+ * function table so that we don't end up dragging in an object just
6
+ * because we call its initialisation function.
7
+ **************************************************************************
8
+ */
9
+
10
+#include "init.h"
11
+
12
+extern struct init_fn init_fns[];
13
+extern struct init_fn init_fns_end[];
14
+
15
+void call_init_fns ( void ) {
16
+	struct init_fn *init_fn;
17
+
18
+	for ( init_fn = init_fns; init_fn < init_fns_end ; init_fn++ ) {
19
+		if ( init_fn->init )
20
+			init_fn->init ();
21
+	}
22
+}
23
+
24
+void call_reset_fns ( void ) {
25
+	struct init_fn *init_fn;
26
+
27
+	for ( init_fn = init_fns; init_fn < init_fns_end ; init_fn++ ) {
28
+		if ( init_fn->reset )
29
+			init_fn->reset ();
30
+	}
31
+}
32
+
33
+void call_exit_fns ( void ) {
34
+	struct init_fn *init_fn;
35
+
36
+	/* 
37
+	 * Exit functions are called in reverse order to
38
+	 * initialisation functions.
39
+	 */
40
+	for ( init_fn = init_fns_end - 1; init_fn >= init_fns ; init_fn-- ) {
41
+		if ( init_fn->exit )
42
+			init_fn->exit ();
43
+	}
44
+}

+ 13
- 124
src/core/main.c View File

@@ -23,12 +23,10 @@ Literature dealing with the network protocols:
23 23
 #include "http.h"
24 24
 #include "timer.h"
25 25
 #include "cpu.h"
26
+#include "console.h"
27
+#include "init.h"
26 28
 #include <stdarg.h>
27 29
 
28
-#ifdef CONSOLE_BTEXT
29
-#include "btext.h"
30
-#endif
31
-
32 30
 #ifdef CONFIG_FILO
33 31
 #include <lib.h>
34 32
 #endif
@@ -43,51 +41,6 @@ int freebsd_howto = 0;
43 41
 char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];
44 42
 #endif
45 43
 
46
-/* in_call(): the entry point to Etherboot.  Generally called from
47
- * arch_in_call(), which in turn will have been invoked from
48
- * platform-specific assembly code.
49
- */
50
-int in_call ( in_call_data_t *data, uint32_t opcode, va_list params ) {
51
-	int old_as_main_program = as_main_program;
52
-	int ret = 0;
53
-
54
-	/* Set flat to indicate that we are not running as the main
55
-	 * program (i.e. we are something like a PXE stack).
56
-	 */
57
-	as_main_program = 0;
58
-
59
-	/* NOTE: params will cease to be valid if we relocate, since
60
-	 * it represents a virtual address
61
-	 */
62
-	switch ( EB_OPCODE(opcode) ) {
63
-		
64
-	case EB_OPCODE_CHECK:
65
-		/* Installation check
66
-		 */
67
-		ret = EB_CHECK_RESULT;
68
-		break;
69
-	case EB_OPCODE_MAIN:
70
-		/* Start up Etherboot as a standalone program. */
71
-		as_main_program = 1;
72
-		ret = main ( data, params );
73
-		break;
74
-#ifdef PXE_EXPORT
75
-	case EB_OPCODE_PXE:
76
-		/* !PXE API call */
77
-		ret = pxe_in_call ( data, params );
78
-		break;
79
-#endif
80
-	default:
81
-		printf ( "Unsupported API \"%c%c\"\n",
82
-			 EB_OPCODE(opcode) >> 8, EB_OPCODE(opcode) & 0xff );
83
-		ret = -1;
84
-		break;
85
-	}
86
-
87
-	as_main_program = old_as_main_program;
88
-	return ret;
89
-}
90
-
91 44
 static inline unsigned long ask_boot(unsigned *index)
92 45
 {
93 46
 	unsigned long order = DEFAULT_BOOT_ORDER;
@@ -166,26 +119,6 @@ static inline void try_floppy_first(void)
166 119
 #endif /* TRY_FLOPPY_FIRST */	
167 120
 }
168 121
 
169
-void console_init(void)
170
-{
171
-#ifdef	CONSOLE_SERIAL
172
-	(void)serial_init();
173
-#endif
174
-#ifdef 	CONSOLE_DIRECT_VGA
175
-       	video_init();
176
-#endif
177
-#ifdef	CONSOLE_BTEXT
178
-	map_boot_text();
179
-#endif
180
-}
181
-
182
-static void console_fini(void)
183
-{
184
-#ifdef	CONSOLE_SERIAL
185
-	(void)serial_fini();
186
-#endif
187
-}
188
-
189 122
 static struct class_operations {
190 123
 	struct dev *dev;
191 124
 	int (*probe)(struct dev *dev);
@@ -204,44 +137,16 @@ static int exit_ok;
204 137
 static int exit_status;
205 138
 static int initialized;
206 139
 
140
+
207 141
 /**************************************************************************
208 142
 MAIN - Kick off routine
209 143
 **************************************************************************/
210
-int main(in_call_data_t *data, va_list params)
211
-{
212
-	char *p;
144
+int main ( void ) {
213 145
 	int state;
214 146
 
215
-	for (p = _bss; p < _ebss; p++)
216
-		*p = 0;	/* Zero BSS */
217
-
218
-	console_init();
219
-	arch_main(data,params);
220
-
221
-#if 0
222
-#ifdef  CONSOLE_BTEXT
223
-        btext_init();
224
-        map_boot_text();
225
-        btext_clearscreen();
226
-#endif
227
-#endif 
228
-
229
-	if ( rom.rom_segment ) {
230
-		printf ( "ROM segment %#hx length %#hx reloc %#x\n",
231
-			 rom.rom_segment, rom.rom_length, _text );
232
-	}
233
-
234
-	cpu_setup();
235
-	setup_timers();
236
-	gateA20_set();
237 147
 	print_config();
238
-	get_memsizes();
239 148
 	cleanup();
240 149
 
241
-#ifdef CONFIG_PCMCIA
242
-	pcmcia_init_all();
243
-#endif
244
-
245 150
 	/* -1:	timeout or ESC
246 151
 	   -2:	error return from loader
247 152
 	   -3:  finish the current run.
@@ -258,10 +163,7 @@ int main(in_call_data_t *data, va_list params)
258 163
 	for(;state != 255;) {
259 164
 		state = main_loop(state);
260 165
 	}
261
-	arch_on_exit(exit_status);
262
-#ifdef CONFIG_PCMCIA
263
-	pcmcia_shutdown_all();
264
-#endif
166
+	/* arch_on_exit(exit_status) */
265 167
 	return exit_status;
266 168
 }
267 169
 
@@ -283,13 +185,11 @@ static int main_loop(int state)
283 185
 	static unsigned boot_index;
284 186
 	static struct dev * dev = 0;
285 187
 	static struct class_operations *ops;
286
-	static void *heap_base;
287 188
 	static int type;
288 189
 	static int i;
289 190
 
290 191
 	if (!initialized) {
291 192
 		initialized = 1;
292
-		console_init();
293 193
 		if (dev && (state >= 1) && (state <= 2)) {
294 194
 			dev->how_probe = PROBE_AWAKE;
295 195
 			dev->how_probe = ops->probe(dev);
@@ -304,21 +204,8 @@ static int main_loop(int state)
304 204
 		static int firsttime = 1;
305 205
 		/* First time through */
306 206
 		if (firsttime) {
307
-			relocate();
207
+			/* relocate(); */
308 208
 			cleanup();
309
-			console_init();
310
-			init_heap();
311
-#ifdef  CONSOLE_BTEXT
312
-			//I need to all allot
313
-		        btext_init(); 
314
-		        map_boot_text();
315
-		        btext_clearscreen();
316
-#else
317
-	#ifdef CONFIG_FILO
318
-			pci_init();
319
-	#endif
320
-#endif
321
-
322 209
 			firsttime = 0;
323 210
 		} 
324 211
 #ifdef	EXIT_IF_NO_OFFER
@@ -327,7 +214,6 @@ static int main_loop(int state)
327 214
 			exit(0);
328 215
 		}
329 216
 #endif
330
-		heap_base = allot(0);
331 217
 		i = -1;
332 218
 		state = 4;
333 219
 		dev = 0;
@@ -339,8 +225,7 @@ static int main_loop(int state)
339 225
 	}
340 226
 	case 4:
341 227
 		cleanup();
342
-		console_init();
343
-		forget(heap_base);
228
+		call_reset_fns();
344 229
 		/* Find a dev entry to probe with */
345 230
 		if (!dev) {
346 231
 			int boot;
@@ -377,7 +262,12 @@ static int main_loop(int state)
377 262
 		break;
378 263
 	case 3:
379 264
 		state = -1;
380
-		heap_base = allot(0);
265
+		/* Removed the following line because it was causing
266
+		 * heap.o to be dragged in unnecessarily.  It's also
267
+		 * slightly puzzling: by resetting heap_base, doesn't
268
+		 * this mean that we permanently leak memory?
269
+		 */
270
+		/* heap_base = allot(0); */
381 271
 		dev->how_probe = ops->probe(dev);
382 272
 		if (dev->how_probe == PROBE_FAILED) {
383 273
 			dev = 0;
@@ -518,7 +408,6 @@ void cleanup(void)
518 408
 	/* Stop receiving packets */
519 409
 	eth_disable();
520 410
 	disk_disable();
521
-	console_fini();
522 411
 	initialized = 0;
523 412
 }
524 413
 

+ 1
- 142
src/core/misc.c View File

@@ -3,13 +3,7 @@ MISC Support Routines
3 3
 **************************************************************************/
4 4
 
5 5
 #include "etherboot.h"
6
-#ifdef CONSOLE_BTEXT
7
-#include <btext.h>
8
-#endif
9
-#ifdef CONSOLE_PC_KBD
10
-#include <pc_kbd.h>
11
-#endif
12
-
6
+#include "console.h"
13 7
 
14 8
 /**************************************************************************
15 9
 IPCHKSUM - Checksum IP Header
@@ -170,7 +164,6 @@ int inet_aton(const char *start, in_addr *i)
170 164
 	return p - start;
171 165
 }
172 166
 
173
-
174 167
 unsigned long strtoul(const char *p, const char **endp, int base)
175 168
 {
176 169
 	unsigned long ret = 0;
@@ -185,140 +178,6 @@ unsigned long strtoul(const char *p, const char **endp, int base)
185 178
 	
186 179
 }
187 180
 
188
-#define K_RDWR		0x60		/* keyboard data & cmds (read/write) */
189
-#define K_STATUS	0x64		/* keyboard status */
190
-#define K_CMD		0x64		/* keybd ctlr command (write-only) */
191
-
192
-#define K_OBUF_FUL	0x01		/* output buffer full */
193
-#define K_IBUF_FUL	0x02		/* input buffer full */
194
-
195
-#define KC_CMD_WIN	0xd0		/* read  output port */
196
-#define KC_CMD_WOUT	0xd1		/* write output port */
197
-#define KB_SET_A20	0xdf		/* enable A20,
198
-					   enable output buffer full interrupt
199
-					   enable data line
200
-					   disable clock line */
201
-#define KB_UNSET_A20	0xdd		/* enable A20,
202
-					   enable output buffer full interrupt
203
-					   enable data line
204
-					   disable clock line */
205
-
206
-enum { Disable_A20 = 0x2400, Enable_A20 = 0x2401, Query_A20_Status = 0x2402,
207
-	Query_A20_Support = 0x2403 };
208
-
209
-#if defined(PCBIOS) && !defined(IBM_L40)
210
-static void empty_8042(void)
211
-{
212
-	unsigned long time;
213
-	char st;
214
-
215
-	time = currticks() + TICKS_PER_SEC;	/* max wait of 1 second */
216
-	while ((((st = inb(K_CMD)) & K_OBUF_FUL) ||
217
-	       (st & K_IBUF_FUL)) &&
218
-	       currticks() < time)
219
-		inb(K_RDWR);
220
-}
221
-#endif	/* IBM_L40 */
222
-
223
-#if defined(PCBIOS)
224
-/*
225
- * Gate A20 for high memory
226
- */
227
-void gateA20_set(void)
228
-{
229
-#warning "gateA20_set should test to see if it is already set"
230
-	if (int15(Enable_A20) == 0) {
231
-		return;
232
-	}
233
-#ifdef	IBM_L40
234
-	outb(0x2, 0x92);
235
-#else	/* IBM_L40 */
236
-	empty_8042();
237
-	outb(KC_CMD_WOUT, K_CMD);
238
-	empty_8042();
239
-	outb(KB_SET_A20, K_RDWR);
240
-	empty_8042();
241
-#endif	/* IBM_L40 */
242
-}
243
-#endif
244
-
245
-
246
-int last_putchar; // From filo
247
-
248
-void
249
-putchar(int c)
250
-{
251
-	c &= 0xff;
252
-	last_putchar = c;
253
-
254
-	if (c == '\n')
255
-		putchar('\r');
256
-#ifdef	CONSOLE_FIRMWARE
257
-	console_putc(c);
258
-#endif
259
-#ifdef	CONSOLE_DIRECT_VGA
260
-	vga_putc(c);
261
-#endif
262
-#ifdef  CONSOLE_BTEXT
263
-        btext_putc(c);
264
-#endif
265
-#ifdef	CONSOLE_SERIAL
266
-	serial_putc(c);
267
-#endif
268
-}
269
-
270
-/**************************************************************************
271
-GETCHAR - Read the next character from input device WITHOUT ECHO
272
-**************************************************************************/
273
-int getchar(void)
274
-{
275
-	int c = 256;
276
-
277
-	do {
278
-#if defined(PCBIOS) && defined(POWERSAVE)
279
-		/* Doze for a while (until the next interrupt).  This works
280
-		 * fine, because the keyboard is interrupt-driven, and the
281
-		 * timer interrupt (approx. every 50msec) takes care of the
282
-		 * serial port, which is read by polling.  This reduces the
283
-		 * power dissipation of a modern CPU considerably, and also
284
-		 * makes Etherboot waiting for user interaction waste a lot
285
-		 * less CPU time in a VMware session.  */
286
-		cpu_nap();
287
-#endif	/* POWERSAVE */
288
-#ifdef	CONSOLE_FIRMWARE
289
-		if (console_ischar())
290
-			c = console_getc();
291
-#endif
292
-#ifdef	CONSOLE_SERIAL
293
-		if (serial_ischar())
294
-			c = serial_getc();
295
-#endif
296
-#ifdef CONSOLE_PC_KBD
297
-		if (kbd_ischar()) 
298
-			c = kbd_getc();
299
-#endif
300
-	} while (c==256);
301
-	if (c == '\r')
302
-		c = '\n';
303
-	return c;
304
-}
305
-
306
-int iskey(void)
307
-{
308
-#ifdef	CONSOLE_FIRMWARE
309
-	if (console_ischar())
310
-		return 1;
311
-#endif
312
-#ifdef	CONSOLE_SERIAL
313
-	if (serial_ischar())
314
-		return 1;
315
-#endif
316
-#ifdef CONSOLE_PC_KBD
317
-        if (kbd_ischar())
318
-		return 1;
319
-#endif
320
-	return 0;
321
-}
322 181
 
323 182
 #if DEBUG_UTILS
324 183
 

+ 20
- 1
src/core/osloader.c View File

@@ -30,6 +30,22 @@ Modifications: Ken Yap (for Etherboot/16)
30 30
  */
31 31
 
32 32
 #include "etherboot.h"
33
+#include "memsizes.h"
34
+
35
+#ifdef KEEP_IT_REAL
36
+
37
+#warning "All download mechanisms are broken under KEEP_IT_REAL"
38
+
39
+os_download_t probe_image(unsigned char *data, unsigned int len) {
40
+	return 0;
41
+}
42
+
43
+int load_block(unsigned char *data, unsigned int block, unsigned int len, int eof) {
44
+	return 1;
45
+}
46
+
47
+#else /* KEEP_IT_REAL */
48
+
33 49
 
34 50
 struct os_entry_regs os_regs;
35 51
 
@@ -128,7 +144,7 @@ static void done(int do_cleanup)
128 144
 	 */
129 145
 	if ( do_cleanup ) {
130 146
 		cleanup();
131
-		arch_on_exit(0);
147
+		/* arch_on_exit(0); */
132 148
 	}
133 149
 }
134 150
 
@@ -261,6 +277,7 @@ PROBE_IMAGE - Detect image file type
261 277
 os_download_t probe_image(unsigned char *data, unsigned int len)
262 278
 {
263 279
 	os_download_t os_download = 0;
280
+
264 281
 #ifdef AOUT_IMAGE
265 282
 	if (!os_download) os_download = aout_probe(data, len);
266 283
 #endif
@@ -286,6 +303,7 @@ os_download_t probe_image(unsigned char *data, unsigned int len)
286 303
 #ifdef RAW_IMAGE
287 304
 	if (!os_download) os_download = raw_probe(data, len);
288 305
 #endif
306
+
289 307
 	return os_download;
290 308
 }
291 309
 
@@ -363,3 +381,4 @@ int load_block(unsigned char *data, unsigned int block, unsigned int len, int eo
363 381
  * End:
364 382
  */
365 383
 
384
+#endif /* KEEP_IT_REAL */

+ 10
- 6
src/core/pc_kbd.c View File

@@ -9,8 +9,9 @@
9 9
  * 2004-04 moved by LYH From filo to Etherboot
10 10
  *		yhlu@tyan.com
11 11
  */
12
-#ifdef CONSOLE_PC_KBD
13
-#include "etherboot.h"
12
+
13
+#include "io.h"
14
+#include "console.h"
14 15
 
15 16
 static char key_map[][128] = {
16 17
     {
@@ -69,14 +70,14 @@ static int get_scancode(void)
69 70
     return scan;
70 71
 }
71 72
 
72
-int kbd_havekey(void)
73
+static int kbd_havekey(void)
73 74
 {
74 75
     if (!cur_scan)
75 76
 	cur_scan = get_scancode();
76 77
     return cur_scan != 0;
77 78
 }
78 79
 
79
-int kbd_ischar(void)
80
+static int kbd_ischar(void)
80 81
 {
81 82
     if (!kbd_havekey())
82 83
 	return 0;
@@ -87,7 +88,7 @@ int kbd_ischar(void)
87 88
     return 1;
88 89
 }
89 90
 
90
-int kbd_getc(void)
91
+static int kbd_getc(void)
91 92
 {
92 93
     int c;
93 94
 
@@ -105,4 +106,7 @@ int kbd_getc(void)
105 106
     cur_scan = 0;
106 107
     return c;
107 108
 }
108
-#endif
109
+
110
+static struct console_driver pc_kbd_console __console_driver = {
111
+	.getchar = kbd_getc,
112
+};

+ 8
- 12
src/core/pcmcia.c View File

@@ -1,5 +1,3 @@
1
-#ifdef CONFIG_PCMCIA
2
-
3 1
 /*
4 2
  *	pcmcia.c
5 3
  *
@@ -25,13 +23,13 @@
25 23
  *	at some point. If there's anything obvious or better, not-so-obvious,
26 24
  *	please contact me by e-mail: anselm (AT) hoffmeister (DOT) be   *THANKS*
27 25
  */
28
-#include "../include/pcmcia.h"
29
-#include "../include/i82365.h"
26
+#include "pcmcia.h"
27
+#include "i82365.h"
30 28
 #define CODE_STATUS "alpha"
31 29
 #define	CODE_VERSION "0.1.3"
32
-
33
-#include "../include/pcmcia-opts.h"
34
-#include "../include/pcmcia.h"
30
+#include "pcmcia-opts.h"
31
+#include "console.h"
32
+#include "init.h"
35 33
 
36 34
 int	sockets; /* AHTODO: Phase this out! */
37 35
 u_int	pccsocks;
@@ -55,7 +53,7 @@ void	sleepticks(int numticks ) {
55 53
 	return;
56 54
 }
57 55
 
58
-int	pcmcia_init_all(void) {
56
+static void pcmcia_init_all(void) {
59 57
 	u_int i, j, k, l, m, n, ui, configs = 0;
60 58
 	u_int multicard[8];
61 59
 	u_char	*uc, upc;
@@ -253,17 +251,15 @@ int	pcmcia_init_all(void) {
253 251
 		getchar();
254 252
 	}
255 253
 
256
-	return 0;
257 254
 }
258 255
 
259
-int	pcmcia_shutdown_all(void) {
256
+static void	pcmcia_shutdown_all(void) {
260 257
 	int i;
261 258
 	//if ( PDEBUG > 2 ) {printf("<press key to continue>\n" ); getchar(); }
262 259
 	for ( i = 0; i < pccsocks; ++i ) {
263 260
  		driver[pccsock[i].drivernum].f(SHUTDOWN,pccsock[i].internalid,0,0,0);
264 261
 	}
265 262
 	printf("Shutdown of PCMCIA subsystem completed");
266
-	return 0;
267 263
 }
268 264
 
269
-#endif /* CONFIG_PCMCIA */
265
+INIT_FN ( INIT_PCMCIA, pcmcia_init_all, NULL, pcmcia_shutdown_all );

+ 0
- 6
src/core/pxe_export.c View File

@@ -1230,17 +1230,11 @@ PXENV_EXIT_t pxenv_undi_loader ( undi_loader_t *loader ) {
1230 1230
 	 * this, but it's currently split interestingly between main()
1231 1231
 	 * and main_loop()...
1232 1232
 	 */
1233
-	console_init();
1234
-	cpu_setup();
1235
-	setup_timers();
1236
-	gateA20_set();
1237 1233
 	print_config();
1238 1234
 	get_memsizes();
1239 1235
 	cleanup();
1240 1236
 	relocate();
1241 1237
 	cleanup();
1242
-	console_init();
1243
-	init_heap();
1244 1238
 
1245 1239
 	/* We have relocated; the loader pointer is now invalid */
1246 1240
 	loader = phys_to_virt ( loader_phys );

+ 3
- 2
src/core/relocate.c View File

@@ -1,6 +1,7 @@
1 1
 #ifndef	NORELOCATE
2 2
 
3 3
 #include "etherboot.h"
4
+#include "memsizes.h"
4 5
 
5 6
 /* by Eric Biederman */
6 7
 
@@ -93,10 +94,10 @@ void relocate(void)
93 94
 		printf("Relocating _text from: [%lx,%lx) to [%lx,%lx)\n",
94 95
 			old_addr, virt_to_phys(_end),
95 96
 			addr, eaddr);
96
-		arch_relocate_to(addr);
97
+		/* arch_relocate_to ( addr ) */
97 98
 		cleanup();
98 99
 		relocate_to(addr);
99
-		arch_relocated_from(old_addr);
100
+		/* arch_relocated_from ( addr ) */
100 101
 	}
101 102
 }
102 103
 

+ 35
- 41
src/core/serial.c View File

@@ -1,7 +1,3 @@
1
-#include "etherboot.h"
2
-#include "timer.h"
3
-#ifdef	CONSOLE_SERIAL
4
-
5 1
 /*
6 2
  * The serial port interface routines implement a simple polled i/o
7 3
  * interface to a standard serial port.  Due to the space restrictions
@@ -15,25 +11,27 @@
15 11
  * parity, 1 stop bit (8N1).  This can be changed in init_serial().
16 12
  */
17 13
 
18
-static int found = 0;
14
+#include "stddef.h"
15
+#include "console.h"
16
+#include "init.h"
17
+#include "io.h"
18
+#include "timer.h"
19
+
20
+/* Set default values if none specified */
19 21
 
20
-#if defined(COMCONSOLE)
21
-#undef UART_BASE
22
-#define UART_BASE COMCONSOLE
22
+#ifndef COMCONSOLE
23
+#define COMCONSOLE ( 0x3f8 )
23 24
 #endif
24 25
 
25
-#ifndef UART_BASE
26
-#error UART_BASE not defined
26
+#ifndef CONSPEED
27
+#define CONSPEED ( 9600 )
27 28
 #endif
28 29
 
29
-#if defined(CONSPEED)
30
+#undef UART_BASE
31
+#define UART_BASE COMCONSOLE
32
+
30 33
 #undef UART_BAUD
31 34
 #define UART_BAUD CONSPEED
32
-#endif
33
-
34
-#ifndef UART_BAUD
35
-#define UART_BAUD 115200
36
-#endif
37 35
 
38 36
 #if ((115200%UART_BAUD) != 0)
39 37
 #error Bad ttys0 baud rate
@@ -83,18 +81,15 @@ static int found = 0;
83 81
 #define uart_writeb(val,addr) outb((val),(addr))
84 82
 #endif
85 83
 
84
+static struct console_driver serial_console;
85
+
86 86
 /*
87 87
  * void serial_putc(int ch);
88 88
  *	Write character `ch' to port UART_BASE.
89 89
  */
90
-void serial_putc(int ch)
91
-{
90
+static void serial_putc ( int ch ) {
92 91
 	int i;
93 92
 	int status;
94
-	if (!found) {
95
-		/* no serial interface */
96
-		return;
97
-	}
98 93
 	i = 1000; /* timeout */
99 94
 	while(--i > 0) {
100 95
 		status = uart_readb(UART_BASE + UART_LSR);
@@ -111,8 +106,7 @@ void serial_putc(int ch)
111 106
  * int serial_getc(void);
112 107
  *	Read a character from port UART_BASE.
113 108
  */
114
-int serial_getc(void)
115
-{
109
+static int serial_getc ( void ) {
116 110
 	int status;
117 111
 	int ch;
118 112
 	do {
@@ -131,11 +125,8 @@ int serial_getc(void)
131 125
  *       If there is a character in the input buffer of port UART_BASE,
132 126
  *       return nonzero; otherwise return 0.
133 127
  */
134
-int serial_ischar(void)
135
-{
128
+static int serial_ischar ( void ) {
136 129
 	int status;
137
-	if (!found)
138
-		return 0;
139 130
 	status = uart_readb(UART_BASE + UART_LSR);	/* line status reg; */
140 131
 	return status & 1;		/* rx char available */
141 132
 }
@@ -144,15 +135,10 @@ int serial_ischar(void)
144 135
  * int serial_init(void);
145 136
  *	Initialize port UART_BASE to speed CONSPEED, line settings 8N1.
146 137
  */
147
-int serial_init(void)
148
-{
149
-	int initialized = 0;
138
+static void serial_init ( void ) {
150 139
 	int status;
151 140
 	int divisor, lcs;
152 141
 
153
-	if (found)
154
-		return 1;
155
-
156 142
 	divisor = COMBRD;
157 143
 	lcs = UART_LCS;
158 144
 
@@ -207,10 +193,9 @@ int serial_init(void)
207 193
 		/* line status reg */
208 194
 		status = uart_readb(UART_BASE + UART_LSR);
209 195
 	} while(status & UART_LSR_DR);
210
-	initialized = 1;
196
+	serial_console.disabled = 0;
211 197
  out:
212
-	found = initialized;
213
-	return initialized;
198
+	return;
214 199
 }
215 200
 
216 201
 /*
@@ -218,10 +203,9 @@ int serial_init(void)
218 203
  *	Cleanup our use of the serial port, in particular flush the
219 204
  *	output buffer so we don't accidentially loose characters.
220 205
  */
221
-void serial_fini(void)
222
-{
206
+static void serial_fini ( void ) {
223 207
 	int i, status;
224
-	if (!found) {
208
+	if (serial_console.disabled) {
225 209
 		/* no serial interface */
226 210
 		return;
227 211
 	}
@@ -232,5 +216,15 @@ void serial_fini(void)
232 216
 	do {
233 217
 		status = uart_readb(UART_BASE + UART_LSR);
234 218
 	} while((--i > 0) && !(status & UART_LSR_TEMPT));
219
+	/* Don't mark it as disabled; it's still usable */
235 220
 }
236
-#endif
221
+
222
+static struct console_driver serial_console __console_driver = {
223
+	.putchar = serial_putc,
224
+	.getchar = serial_getc,
225
+	.iskey = serial_ischar,
226
+	.disabled = 1,
227
+};
228
+
229
+INIT_FN ( INIT_CONSOLE, serial_init, NULL, serial_fini );
230
+

+ 2
- 1
src/drivers/disk/ide_disk.c View File

@@ -759,7 +759,8 @@ static int ide_pci_probe(struct dev *dev, struct pci_device *pci)
759 759
 }
760 760
 #define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
761 761
 static struct pci_id ide_controllers[] = {
762
-{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801CA_11,    "PIIX4" },
762
+	PCI_ROM(0x0000, 0x0000, "ide_disk", "Generic IDE disk support"),
763
+/* { PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801CA_11,    "PIIX4" },*/
763 764
 #if 0  /* Currently I don't need any entries in this table so ignore it */
764 765
 { PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82371FB_0,     "PIIX" },
765 766
 { PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82371FB_1,     "PIIX" },

+ 2
- 0
src/drivers/net/3c509.c View File

@@ -653,6 +653,7 @@ static struct isa_driver t509_driver __isa_driver = {
653 653
 	.probe   = t509_probe,
654 654
 	.ioaddrs = 0,
655 655
 };
656
+ISA_ROM("3c509","3c509, ISA/EISA");
656 657
 #endif
657 658
 
658 659
 #ifdef INCLUDE_3C529
@@ -662,6 +663,7 @@ static struct isa_driver t529_driver __isa_driver = {
662 663
 	.probe   = t529_probe,
663 664
 	.ioaddrs = 0,
664 665
 };
666
+ISA_ROM("3c529","3c529 == MCA 3c509");
665 667
 #endif
666 668
 
667 669
 /*

+ 1
- 0
src/drivers/net/3c515.c View File

@@ -812,3 +812,4 @@ static struct isa_driver t515_driver __isa_driver = {
812 812
 	.probe = t515_probe,
813 813
 	.ioaddrs = 0,
814 814
 };
815
+ISA_ROM("3c515","3c515, Fast EtherLink ISA");

+ 1
- 0
src/drivers/net/cs89x0.c View File

@@ -711,6 +711,7 @@ static struct isa_driver cs89x0_driver __isa_driver = {
711 711
 	.probe   = cs89x0_probe,
712 712
 	.ioaddrs = 0,
713 713
 };
714
+ISA_ROM("cs89x0","Crystal Semiconductor CS89x0");
714 715
 
715 716
 /*
716 717
  * Local variables:

+ 1
- 0
src/drivers/net/depca.c View File

@@ -792,3 +792,4 @@ static struct isa_driver depca_driver __isa_driver = {
792 792
 	.probe   = depca_probe,
793 793
 	.ioaddrs = 0,
794 794
 };
795
+ISA_ROM("depca","Digital DE100 and DE200");

+ 1
- 0
src/drivers/net/eepro.c View File

@@ -623,3 +623,4 @@ static struct isa_driver eepro_driver __isa_driver = {
623 623
 	.probe   = eepro_probe,
624 624
 	.ioaddrs = 0,
625 625
 };
626
+ISA_ROM("eepro","Intel Etherexpress Pro/10");

+ 19
- 19
src/drivers/net/ns83820.c View File

@@ -370,25 +370,6 @@ struct ring_desc {
370 370
 };
371 371
 #endif
372 372
 
373
-/* Define the TX Descriptor */
374
-static struct ring_desc tx_ring[NR_TX_DESC]
375
-    __attribute__ ((aligned(8)));
376
-
377
-/* Create a static buffer of size REAL_RX_BUF_SIZE for each
378
-TX Descriptor.  All descriptors point to a
379
-part of this buffer */
380
-static unsigned char txb[NR_TX_DESC * REAL_RX_BUF_SIZE];
381
-
382
-/* Define the TX Descriptor */
383
-static struct ring_desc rx_ring[NR_RX_DESC]
384
-    __attribute__ ((aligned(8)));
385
-
386
-/* Create a static buffer of size REAL_RX_BUF_SIZE for each
387
-RX Descriptor   All descriptors point to a
388
-part of this buffer */
389
-static unsigned char rxb[NR_RX_DESC * REAL_RX_BUF_SIZE]
390
-    __attribute__ ((aligned(8)));
391
-
392 373
 /* Private Storage for the NIC */
393 374
 struct ns83820_private {
394 375
 	u8 *base;
@@ -412,6 +393,25 @@ struct ns83820_private {
412 393
 } nsx;
413 394
 static struct ns83820_private *ns;
414 395
 
396
+/* Define the TX Descriptor */
397
+static struct ring_desc tx_ring[NR_TX_DESC]
398
+    __attribute__ ((aligned(8)));
399
+
400
+/* Create a static buffer of size REAL_RX_BUF_SIZE for each
401
+TX Descriptor.  All descriptors point to a
402
+part of this buffer */
403
+static unsigned char txb[NR_TX_DESC * REAL_RX_BUF_SIZE];
404
+
405
+/* Define the TX Descriptor */
406
+static struct ring_desc rx_ring[NR_RX_DESC]
407
+    __attribute__ ((aligned(8)));
408
+
409
+/* Create a static buffer of size REAL_RX_BUF_SIZE for each
410
+RX Descriptor   All descriptors point to a
411
+part of this buffer */
412
+static unsigned char rxb[NR_RX_DESC * REAL_RX_BUF_SIZE]
413
+    __attribute__ ((aligned(8)));
414
+
415 415
 static void phy_intr(struct nic *nic __unused)
416 416
 {
417 417
 	static char *speeds[] =

+ 3
- 1
src/drivers/net/ns8390.c View File

@@ -961,6 +961,7 @@ static struct isa_driver wd_driver __isa_driver = {
961 961
 	.probe   = wd_probe,
962 962
 	.ioaddrs = 0, 
963 963
 };
964
+ISA_ROM("wd","WD8003/8013, SMC8216/8416, SMC 83c790 (EtherEZ)");
964 965
 #endif
965 966
 
966 967
 #ifdef	INCLUDE_3C503
@@ -970,6 +971,7 @@ static struct isa_driver t503_driver __isa_driver = {
970 971
 	.probe   = t503_probe,
971 972
 	.ioaddrs = 0, 
972 973
 };
974
+ISA_ROM("3c503","3Com503, Etherlink II[/16]");
973 975
 #endif
974 976
 
975 977
 #ifdef	INCLUDE_NE
@@ -979,6 +981,7 @@ static struct isa_driver ne_driver __isa_driver = {
979 981
 	.probe   = ne_probe,
980 982
 	.ioaddrs = 0, 
981 983
 };
984
+ISA_ROM("ne","NE1000/2000 and clones");
982 985
 #endif
983 986
 
984 987
 #ifdef	INCLUDE_NS8390
@@ -1013,4 +1016,3 @@ static struct pci_driver nepci_driver __pci_driver = {
1013 1016
  *  c-basic-offset: 8
1014 1017
  * End:
1015 1018
  */
1016
-

+ 3
- 1
src/drivers/net/prism2_pci.c View File

@@ -18,7 +18,9 @@ $Id$
18 18
 #include "prism2.c"
19 19
 
20 20
 static struct pci_id prism2_pci_nics[] = {
21
-PCI_ROM(0x1260, 0x3873, "prism2_pci", "Harris Semiconductor Prism2.5 clone"),	/* Generic Prism2.5 PCI device */
21
+PCI_ROM(0x1260, 0x3873, "prism2_pci",	"Harris Semiconductor Prism2.5 clone"),
22
+PCI_ROM(0x1260, 0x3873, "hwp01170",	"ActionTec HWP01170"),
23
+PCI_ROM(0x1260, 0x3873, "dwl520",	"DLink DWL-520"),
22 24
 };
23 25
 
24 26
 static struct pci_driver prism2_pci_driver __pci_driver = {

+ 1
- 0
src/drivers/net/sk_g16.c View File

@@ -1187,3 +1187,4 @@ static struct isa_driver SK_driver __isa_driver = {
1187 1187
 	.probe   = SK_probe,
1188 1188
 	.ioaddrs = 0,
1189 1189
 };
1190
+ISA_ROM("sk_g16","Schneider and Koch G16");

+ 1
- 0
src/drivers/net/smc9000.c View File

@@ -542,3 +542,4 @@ static struct isa_driver smc9000_driver __isa_driver = {
542 542
 	.probe   = smc9000_probe,
543 543
 	.ioaddrs = 0,
544 544
 };
545
+ISA_ROM("smc9000","SMC9000");

+ 0
- 376
src/genrules.pl View File

@@ -1,376 +0,0 @@
1
-#!/usr/bin/perl -w
2
-#
3
-#	Helper program to generate Makefile rules into file Rom from table in
4
-#	file NIC
5
-#
6
-#	GPL, Ken Yap 2001, with major contributions by Klaus Espenlaub
7
-#	Revised 2002
8
-#
9
-
10
-use strict;
11
-
12
-use bytes;
13
-
14
-use File::Basename;
15
-
16
-use vars qw($familyfile $nic @families $curfam %drivers %pcient %isaent %isalist %buildent $arch @srcs);
17
-
18
-sub __gendep ($$$)
19
-{
20
-	my ($file, $deps, $driver_dep) = @_;
21
-	foreach my $source (@$deps) {
22
-		my $inc;
23
-		my @collect_dep = ();
24
-		$inc = "arch/$arch/include/$source" unless ! -e "arch/$arch/include/$source";
25
-		$inc = "include/$source" unless ! -e "include/$source";
26
-		$inc = dirname($file) . "/$source" unless ! -e dirname($file) . "/$source";
27
-		unless (defined($inc)) {
28
-			print STDERR "$source from $file not found (shouldn't happen)\n";
29
-			next;
30
-		};
31
-		next if (exists ${$driver_dep}{$inc});
32
-		${$driver_dep}{$inc} = $inc;
33
-# Warn about failure to open, then skip, rather than soldiering on with the read
34
-		unless (open(INFILE, "$inc")) {
35
-			print STDERR "$inc: $! (shouldn't happen)\n";
36
-			next;
37
-		};
38
-		while (<INFILE>) {
39
-			chomp($_);
40
-# This code is not very smart: no C comments or CPP conditionals processing is
41
-# done.  This may cause unexpected (or incorrect) additional dependencies.
42
-# However, ignoring the CPP conditionals is in some sense correct: we need to
43
-# figure out a superset of all the headers for the driver source.  
44
-			next unless (s/^\s*#include\s*"([^"]*)".*$/$1/);
45
-# Ignore system includes, like the ones in osdep.h
46
-			next if ($_ =~ m:^/:);
47
-# Ignore "special" includes, like .buildserial.h
48
-		        next if /^\./;
49
-			push(@collect_dep, $_);
50
-		}
51
-		close(INFILE);
52
-		if (@collect_dep) {
53
-			&__gendep($inc, \@collect_dep, $driver_dep);
54
-		}
55
-	}
56
-}
57
-
58
-sub gendep ($) {
59
-	my ($driver) = @_;
60
-
61
-	# Automatically generate the dependencies for the driver sources.
62
-	my %driver_dep = ();
63
-	__gendep( "", [ $driver ], \%driver_dep);
64
-	return sort values %driver_dep
65
-}
66
-
67
-# Make sure that every rom name exists only once.
68
-# make will warn if it finds duplicate rules, but it is better to stop
69
-sub checkduplicate (\%$$) {
70
-	my ($anyent, $curfam, $romname) = @_;
71
-	foreach my $family (@families) {
72
-		if (exists($$anyent{$family})) {
73
-			my $aref = $$anyent{$family};
74
-			foreach my $entry (@$aref) {
75
-				if ($entry->[0] eq $romname) {
76
-					print STDERR "\nROM name $romname defined twice. Please correct.\n";
77
-					exit 1;
78
-				}
79
-			}
80
-		}
81
-	}
82
-}
83
-
84
-sub genroms($) {
85
-	my ($driver) = @_;
86
-	
87
-	# Automatically discover the ROMS this driver can produce.
88
-	unless (open(INFILE, "$driver")) {
89
-		print STDERR "$driver: %! (shouldn't happen)\n";
90
-		next;
91
-	};
92
-	while (<INFILE>) {
93
-		chomp($_);
94
-		if ($_ =~ m/^\s*PCI_ROM\(\s*0x([0-9A-Fa-f]*)\s*,\s*0x([0-9A-Fa-f]*)\s*,\s*"([^"]*)"\s*,\s*"([^"]*)"\)/) {
95
-
96
-			# We store a list of PCI IDs and comments for each PC target
97
-			my ($vendor_id, $device_id, $rom, $comment) = (hex($1), hex($2), $3, $4);
98
-			my $ids = sprintf("0x%04x,0x%04x", $vendor_id, $device_id);
99
-			checkduplicate(%pcient, $curfam, $rom);
100
-			push(@{$pcient{$curfam}}, [$rom, $ids, $comment]);
101
-		}
102
-		elsif($_ =~ m/^\s*ISA_ROM\(\s*"([^"]*)"\s*,\s*"([^"]*)"\)/) {
103
-			my ($rom, $comment) = ($1, $2);
104
-			# We store the base driver file for each ISA target
105
-			$isalist{$rom} = $curfam;
106
-			$buildent{$rom} = 1;
107
-			checkduplicate(%isaent, $curfam, $rom);
108
-			push(@{$isaent{$curfam}}, [$rom, $comment]);
109
-		}
110
-		elsif($_ =~ m/^\s*PCI_ROM/ or $_ =~ m/^\s*ISA_ROM/) {
111
-			# Complain since we cannot parse this. Of course it would be nicer if we could parse...
112
-			print STDERR "\nFound incomplete PCI_ROM or ISA_ROM macro in file $driver.\n";
113
-			print STDERR "ROM macros spanning more than one line are not supported,\n";
114
-			print STDERR "please adjust $driver accordingly.\n\n\n";
115
-			exit 1;
116
-		}
117
-	}
118
-}
119
-
120
-sub addfam ($) {
121
-	my ($family) = @_;
122
-
123
-	push(@families, $family);
124
-	# We store the list of dependencies in the hash for each family
125
-	my @deps = &gendep("$family.c");
126
-	$drivers{$family} = join(' ', @deps);
127
-	$pcient{$family} = [];
128
-	genroms("$family.c");
129
-}
130
-
131
-sub addrom ($) {
132
-	my ($rom, $ids, $comment) = split(' ', $_[0], 3);
133
-
134
-	# defaults if missing
135
-	$ids = '-' unless ($ids);
136
-	$comment = $rom unless ($comment);
137
-	if ($ids ne '-') {
138
-		# We store a list of PCI IDs and comments for each PCI target
139
-		checkduplicate(%pcient, $curfam, $rom);
140
-		push(@{$pcient{$curfam}}, [$rom, $ids, $comment]);
141
-	} else {
142
-		# We store the base driver file for each ISA target
143
-		$isalist{$rom} = $curfam;
144
-		$buildent{$rom} = 1;
145
-		checkduplicate(%isaent, $curfam, $rom);
146
-		push(@{$isaent{$curfam}}, [$rom, $comment]);
147
-	}
148
-}
149
-
150
-# Return true if this driver is ISA only
151
-sub isaonly ($) {
152
-	my $aref = $pcient{$_[0]};
153
-
154
-	return ($#$aref < 0);
155
-}
156
-
157
-$#ARGV >= 1 or die "Usage: $0 Families bin/NIC arch sources...\n";
158
-$familyfile = shift(@ARGV);
159
-$nic  = shift(@ARGV);
160
-$arch = shift(@ARGV);
161
-@srcs = @ARGV;
162
-open FAM, "<$familyfile" or die "Could not open $familyfile: $!\n";
163
-
164
-$curfam = '';
165
-while ( <FAM> ) {
166
-	chomp($_);
167
-	next if (/^\s*(#.*)?$/);
168
-	my ($keyword) = split(' ', $_ , 2);
169
-	if ($keyword eq 'family') {
170
-		my ($keyword, $driver) = split(' ', $_, 2);
171
-		$curfam = '';
172
-		if (! -e "$driver.c") {
173
-			print STDERR "Driver file $driver.c not found, skipping...\n";
174
-			next;
175
-		}
176
-		if ($driver =~ "^arch" && $driver !~ "^arch/$arch") {
177
-# This warning just makes noise for most compilations.
178
-#			print STDERR "Driver file $driver.c not for arch $arch, skipping...\n";
179
-			next;
180
-		}
181
-		&addfam($curfam = $driver);
182
-	} else {
183
-		# skip until we have a valid family
184
-		next if ($curfam eq '');
185
-		&addrom($_);
186
-	}
187
-}
188
-close FAM;
189
-
190
-open(N,">$nic") or die "$nic: $!\n";
191
-print N <<EOF;
192
-# This is an automatically generated file, do not edit
193
-# It does not affect anything in the build, it's only for rom-o-matic
194
-
195
-EOF
196
-foreach my $family (@families) {
197
-	print N "family\t$family\n";
198
-	if (exists($pcient{$family})) {
199
-		my $aref = $pcient{$family};
200
-		foreach my $entry (@$aref) {
201
-			my $rom = $entry->[0];
202
-			my $ids = $entry->[1];
203
-			my $comment = $entry->[2];
204
-			print N "$rom\t$ids\t$comment\n";
205
-		}
206
-	}
207
-	if (exists($isaent{$family})) {
208
-		my $aref = $isaent{$family};
209
-		foreach my $entry (@$aref) {
210
-			my $rom = $entry->[0];
211
-			my $comment = $entry->[1];
212
-			print N "$rom\t-\t$comment\n";
213
-		}
214
-	}
215
-	print N "\n";
216
-}
217
-close(N);
218
-
219
-# Generate the normal source dependencies
220
-print "# Core object file dependencies\n";
221
-foreach my $source (@srcs) {
222
-	next if ($source !~ '[.][cS]$');
223
-	my @deps = &gendep($source);
224
-	my $obj = $source;
225
-	$obj =~ s/^.*?([^\/]+)\.[cS]/bin\/$1.o/;
226
-	foreach my $dep (@deps) {
227
-		print "$obj: $dep\n";
228
-	}
229
-	print("\n");
230
-}
231
-
232
-# Generate the assignments to DOBJS and BINS
233
-print "# Driver object files and ROM image files\n";
234
-print "DOBJS\t:=\n";
235
-print "PCIOBJS\t:=\n";
236
-
237
-print "# Target formats\n";
238
-print "EB_ISOS\t:=\n";
239
-print "EB_LISOS\t:=\n";
240
-print "EB_COMS\t:=\n";
241
-print "EB_EXES\t:=\n";
242
-print "EB_LILOS\t:=\n";
243
-print "EB_ZLILOS\t:=\n";
244
-print "EB_PXES\t:=\n";
245
-print "EB_ZPXES\t:=\n";
246
-print "EB_DSKS\t:=\n";
247
-print "EB_ZDSKS\t:=\n";
248
-print "EB_ELFS\t:=\n";
249
-print "EB_ZELFS\t:=\n";
250
-print "EB_LMELFS\t:=\n";
251
-print "EB_ZLMELFS\t:=\n";
252
-print "EB_ELFDS\t:=\n";
253
-print "EB_ZELFDS\t:=\n";
254
-print "EB_LMELFDS\t:=\n";
255
-print "EB_ZLMELFDS\t:=\n";
256
-
257
-foreach my $pci (sort keys %pcient) {
258
-	my $img = basename($pci);
259
-
260
-	print "DOBJS\t+= \$(BIN)/$img.o\n";
261
-	print "PCIOBJS\t+= \$(BIN)/$img.o\n" unless isaonly($pci);
262
-
263
-# Output targets
264
-	print "EB_LILOS\t+= \$(BIN)/$img.lilo \nEB_ZLILOS\t+= \$(BIN)/$img.zlilo\n";
265
-	print "EB_PXES\t+= \$(BIN)/$img.pxe   \nEB_ZPXES\t+= \$(BIN)/$img.zpxe\n";
266
-	print "EB_DSKS\t+= \$(BIN)/$img.dsk   \nEB_ZDSKS\t+= \$(BIN)/$img.zdsk\n";
267
-	print "EB_ELFS\t+= \$(BIN)/$img.elf   \nEB_ZELFS\t+= \$(BIN)/$img.zelf\n";
268
-	print "EB_LMELFS\t+= \$(BIN)/$img.lmelf \nEB_ZLMELFS\t+= \$(BIN)/$img.zlmelf\n";
269
-	print "EB_ELFDS\t+= \$(BIN)/$img.elfd   \nEB_ZELFDS\t+= \$(BIN)/$img.zelfd\n";
270
-	print "EB_LMELFDS\t+= \$(BIN)/$img.lmelfd \nEB_ZLMELFDS\t+= \$(BIN)/$img.zlmelfd\n";
271
-	print "EB_BIMAGES\t+= \$(BIN)/$img.bImage \nEB_BZIMAGES\t+= \$(BIN)/$img.bzImage\n";
272
-	print "EB_ISOS\t+= \$(BIN)/$img.iso\n";
273
-	print "EB_LISOS\t+= \$(BIN)/$img.liso\n";
274
-	print "EB_COMS\t+= \$(BIN)/$img.com\n";
275
-	print "EB_EXES\t+= \$(BIN)/$img.exe\n";
276
-}
277
-
278
-foreach my $img (sort keys %buildent) {
279
-
280
-	print "DOBJS\t+= \$(BIN)/$img.o\n";
281
-
282
-# Output targets
283
-	print "EB_LILOS\t+= \$(BIN)/$img.lilo \nEB_ZLILOS\t+= \$(BIN)/$img.zlilo\n";
284
-	print "EB_PXES\t+= \$(BIN)/$img.pxe   \nEB_ZPXES\t+= \$(BIN)/$img.zpxe\n";
285
-	print "EB_DSKS\t+= \$(BIN)/$img.dsk   \nEB_ZDSKS\t+= \$(BIN)/$img.zdsk\n";
286
-	print "EB_ELFS\t+= \$(BIN)/$img.elf   \nEB_ZELFS\t+= \$(BIN)/$img.zelf\n";
287
-	print "EB_LMELFS\t+= \$(BIN)/$img.lmelf \nEB_ZLMELFS\t+= \$(BIN)/$img.zlmelf\n";
288
-	print "EB_ELFDS\t+= \$(BIN)/$img.elfd   \nEB_ZELFDS\t+= \$(BIN)/$img.zelfd\n";
289
-	print "EB_LMELFDS\t+= \$(BIN)/$img.lmelfd \nEB_ZLMELFDS\t+= \$(BIN)/$img.zlmelfd\n";
290
-	print "EB_BIMAGES\t+= \$(BIN)/$img.bImage \nEB_BZIMAGE\t+= \$(BIN)/$img.bzImage\n";
291
-	print "EB_ISOS\t+= \$(BIN)/$img.iso\n";
292
-	print "EB_LISOS\t+= \$(BIN)/$img.liso\n";
293
-	print "EB_COMS\t+= \$(BIN)/$img.com\n";
294
-	print "EB_EXES\t+= \$(BIN)/$img.exe\n";
295
-}
296
-
297
-print "ROMS\t:=\n";
298
-foreach my $family (sort keys %pcient) {
299
-	my $aref = $pcient{$family};
300
-	foreach my $entry (@$aref) {
301
-		my $rom = $entry->[0];
302
-		print "ROMS\t+= \$(BIN)/$rom.rom \$(BIN)/$rom.zrom\n";
303
-	}
304
-}
305
-foreach my $isa (sort keys %isalist) {
306
-	print "ROMS\t+= \$(BIN)/$isa.rom \$(BIN)/$isa.zrom\n";
307
-}
308
-
309
-# Generate the *.o rules
310
-print "\n# Rules to build the driver object files\n";
311
-foreach my $pci (sort keys %drivers) {
312
-	# For ISA the rule for .o will generated later
313
-	next if isaonly($pci);
314
-	# PCI drivers are compiled only once for all ROMs
315
-	(my $macro = basename($pci)) =~ tr/\-/_/;
316
-	my $obj = basename($pci);
317
-	my $deps = $drivers{$pci};
318
-	print <<EOF;
319
-
320
-\$(BIN)/$obj.o:	$pci.c \$(MAKEDEPS) $deps
321
-	\$(CC) \$(CFLAGS) \$(\U$macro\EFLAGS) -o \$@ -c \$<
322
-
323
-\$(BIN)/$obj--%.o:	\$(BIN)/%.o \$(BIN)/$obj.o \$(MAKEDEPS)
324
-	\$(LD) -r \$(BIN)/$obj.o \$< -o \$@
325
-
326
-EOF
327
-}
328
-
329
-# Do the ISA entries
330
-foreach my $isa (sort keys %isalist) {
331
-	(my $macro = $isa) =~ tr/\-/_/;
332
-	my $base = $isalist{$isa};
333
-	my $deps = $drivers{$base};
334
-	print <<EOF;
335
-\$(BIN)/$isa.o:	$base.c \$(MAKEDEPS) $deps
336
-	\$(CC) \$(CFLAGS) \$(\U$macro\EFLAGS) -o \$@ -c \$<
337
-
338
-\$(BIN)/$isa--%.o:	\$(BIN)/%.o \$(BIN)/$isa.o \$(MAKEDEPS)
339
-	\$(LD) -r \$(BIN)/$isa.o \$< -o \$@ 
340
-EOF
341
-}
342
-
343
-# Generate the Rom rules
344
-print "# Rules to build the ROM files\n";
345
-foreach my $family (sort keys %pcient) {
346
-	next if isaonly($family);
347
-	my $img = basename($family);
348
-	print <<EOF;
349
-ROMTYPE_$img = PCI
350
-EOF
351
-	my $aref = $pcient{$family};
352
-	foreach my $entry (@$aref) {
353
-		my ($rom, $ids, $comment) = @$entry;
354
-		next if ($ids eq '-');
355
-		print <<EOF;
356
-ROMTYPE_$rom = PCI
357
-MAKEROM_ID_$rom = -p $ids
358
-
359
-EOF
360
-		next if($rom eq $img);
361
-		print <<EOF;
362
-\$(BIN)/$rom\%rom: \$(BIN)/$img\%rom
363
-	cat \$< > \$@
364
-	\$(MAKEROM) \$(MAKEROM_FLAGS) \$(MAKEROM_\$(ROMCARD)) \$(MAKEROM_ID_\$(ROMCARD)) -i\$(IDENT) \$@
365
-
366
-EOF
367
-	}
368
-}
369
-
370
-# ISA ROMs are prepared from the matching code images
371
-# Think this can probably be removed, but not sure
372
-foreach my $isa (sort keys %isalist) {
373
-	print <<EOF;
374
-EOF
375
-}
376
-

+ 1
- 15
src/include/btext.h View File

@@ -32,7 +32,7 @@ typedef struct boot_infos
32 32
     /* Some infos about the current MacOS display */
33 33
     u32       dispDeviceRect[4];       /* left,top,right,bottom */
34 34
     u32       dispDeviceDepth;         /* (8, 16 or 32) */
35
-    u8*       dispDeviceBase;          /* base address (physical) */
35
+    u32       dispDeviceBase;          /* base address (physical) */
36 36
     u32       dispDeviceRowBytes;      /* rowbytes (in bytes) */
37 37
     u32       dispDeviceColorsOffset;  /* Colormap (8 bits only) or 0 (*) */
38 38
 
@@ -56,21 +56,7 @@ typedef struct boot_infos
56 56
  * Benjamin Herrenschmidt <benh@kernel.crashing.org>
57 57
  */
58 58
 
59
-extern void btext_clearscreen(void);
60
-
61 59
 extern boot_infos_t disp_bi;
62 60
 extern u32 boot_text_mapped;
63 61
 
64
-void btext_setup_display(u32 width, u32 height, u32 depth, u32 pitch,
65
-			 unsigned long address);
66
-void map_boot_text(void);
67
-
68
-void btext_drawchar(char c);
69
-void btext_drawstring(const char *str);
70
-void btext_drawhex(u32 v);
71
-
72
-void btext_putc(int c);
73
-
74
-void btext_init(void);
75
-
76 62
 #endif /* _BTEXT_H */

+ 41
- 0
src/include/compiler.h View File

@@ -0,0 +1,41 @@
1
+#ifndef COMPILER_H
2
+#define COMPILER_H
3
+
4
+/* We export the symbol obj_OBJECT (OBJECT is defined on command-line)
5
+ * as a global symbol, so that the linker can drag in selected object
6
+ * files from the library using -u obj_OBJECT.
7
+ *
8
+ * Not quite sure why cpp requires two levels of macro call in order
9
+ * to actually expand OBJECT...
10
+ */
11
+#undef _H1
12
+#define _H1( x, y ) x ## y
13
+#undef _H2
14
+#define _H2( x, y ) _H1 ( x, y )
15
+#define OBJECT_SYMBOL _H2 ( obj_, OBJECT )
16
+#undef _STR
17
+#define _STR(s) #s
18
+#undef _XSTR
19
+#define _XSTR(s) _STR(s)
20
+#define OBJECT_SYMBOL_STR _XSTR ( OBJECT_SYMBOL )
21
+
22
+#ifdef ASSEMBLY
23
+
24
+	.globl	OBJECT_SYMBOL
25
+	.equ	OBJECT_SYMBOL, 0
26
+
27
+#else /* ASSEMBLY */
28
+
29
+__asm__ ( ".globl\t" OBJECT_SYMBOL_STR );
30
+__asm__ ( ".equ\t" OBJECT_SYMBOL_STR ", 0" );
31
+
32
+#define REQUIRE_OBJECT(object) \
33
+	__asm__ ( ".equ\tneed_" #object ", obj_" #object );
34
+
35
+#define PACKED __attribute__((packed))
36
+#define __unused __attribute__((unused))
37
+#define __used __attribute__((used))
38
+
39
+#endif /* ASSEMBLY */
40
+
41
+#endif /* COMPILER_H */

+ 28
- 0
src/include/console.h View File

@@ -0,0 +1,28 @@
1
+#ifndef CONSOLE_H
2
+#define CONSOLE_H
3
+
4
+#include "stdint.h"
5
+
6
+/*
7
+ * Consoles that cannot be used before their INIT_FN() has completed
8
+ * should set disabled = 1 initially.  This allows other console
9
+ * devices to still be used to print out early debugging messages.
10
+ */
11
+
12
+struct console_driver {
13
+	int disabled;
14
+	void ( *putchar ) ( int character );
15
+	int ( *getchar ) ( void );
16
+	int ( *iskey ) ( void );
17
+};
18
+
19
+#define __console_driver \
20
+	__attribute__ (( used, __section__ ( ".drivers.console" ) ))
21
+
22
+/* Function prototypes */
23
+
24
+extern void putchar ( int character );
25
+extern int getchar ( void );
26
+extern int iskey ( void );
27
+
28
+#endif /* CONSOLE_H */

+ 1
- 63
src/include/etherboot.h View File

@@ -49,28 +49,6 @@
49 49
 #define DEFAULT_BOOTFILE	PXENFSROOTPATH "/boot/pxeboot"
50 50
 #endif
51 51
 
52
-/* Clean up console settings... mainly CONSOLE_FIRMWARE and CONSOLE_SERIAL are used
53
- * in the sources (except start.S and serial.S which cannot include
54
- * etherboot.h).  At least one of the CONSOLE_xxx has to be set, and
55
- * CONSOLE_DUAL sets both CONSOLE_CRT and CONSOLE_SERIAL.  If none is set,
56
- * CONSOLE_CRT is assumed.  */
57
-#ifdef CONSOLE_CRT
58
-#define CONSOLE_FIRMWARE
59
-#endif
60
-#ifdef	CONSOLE_DUAL
61
-#undef CONSOLE_FIRMWARE
62
-#define CONSOLE_FIRMWARE
63
-#undef CONSOLE_SERIAL
64
-#define CONSOLE_SERIAL
65
-#endif
66
-#if	defined(CONSOLE_FIRMWARE) && defined(CONSOLE_SERIAL)
67
-#undef CONSOLE_DUAL
68
-#define CONSOLE_DUAL
69
-#endif
70
-#if	!defined(CONSOLE_FIRMWARE) && !defined(CONSOLE_SERIAL)
71
-#define CONSOLE_FIRMWARE
72
-#endif
73
-
74 52
 #if	!defined(DOWNLOAD_PROTO_TFTP) && !defined(DOWNLOAD_PROTO_NFS) && !defined(DOWNLOAD_PROTO_SLAM) && !defined(DOWNLOAD_PROTO_TFTM) && !defined(DOWNLOAD_PROTO_DISK) && !defined(DOWNLOAD_PROTO_HTTP)
75 53
 #error No download protocol defined!
76 54
 #endif
@@ -204,7 +182,7 @@ External prototypes
204 182
 struct Elf_Bhdr;
205 183
 extern int in_call(in_call_data_t *data, uint32_t opcode, va_list params);
206 184
 extern void console_init(void); 
207
-extern int main(in_call_data_t *data, va_list params);
185
+extern int main();
208 186
 extern int loadkernel P((const char *fname));
209 187
 extern char as_main_program;
210 188
 /* nic.c */
@@ -287,26 +265,6 @@ extern unsigned long strtoul P((const char *p, const char **, int base));
287 265
 extern void printf P((const char *, ...));
288 266
 extern int sprintf P((char *, const char *, ...));
289 267
 extern int inet_aton P((const char *p, in_addr *i));
290
-#ifdef PCBIOS
291
-extern void gateA20_set P((void));
292
-#define gateA20_unset()
293
-#else
294
-#define gateA20_set()
295
-#define gateA20_unset()
296
-#endif
297
-extern void putchar P((int));
298
-extern int getchar P((void));
299
-extern int iskey P((void));
300
-
301
-/* pcbios.S */
302
-extern int console_getc P((void));
303
-extern void console_putc P((int));
304
-extern int console_ischar P((void));
305
-extern int getshift P((void));
306
-extern int int15 P((int));
307
-#ifdef	POWERSAVE
308
-extern void cpu_nap P((void));
309
-#endif	/* POWERSAVE */
310 268
 
311 269
 /* basemem.c */
312 270
 extern uint32_t get_free_base_memory ( void );
@@ -318,26 +276,6 @@ extern void free_unused_base_memory ( void );
318 276
 extern void forget_prefix_base_memory ( void );
319 277
 extern void forget_runtime_base_memory ( uint32_t old_addr );
320 278
 
321
-struct e820entry {
322
-	uint64_t addr;
323
-	uint64_t size;
324
-	uint32_t type;
325
-#define E820_RAM	1
326
-#define E820_RESERVED	2
327
-#define E820_ACPI	3 /* usable as RAM once ACPI tables have been read */
328
-#define E820_NVS	4
329
-} PACKED;
330
-#define E820ENTRY_SIZE 20
331
-#define E820MAX 32
332
-struct meminfo {
333
-	uint16_t basememsize;
334
-	uint16_t pad;
335
-	uint32_t memsize;
336
-	uint32_t map_count;
337
-	struct e820entry map[E820MAX];
338
-} PACKED;
339
-extern struct meminfo meminfo;
340
-extern void get_memsizes(void);
341 279
 extern unsigned long get_boot_order(unsigned long order, unsigned *index);
342 280
 #ifndef NORELOCATE
343 281
 extern void relocate(void);

+ 58
- 0
src/include/init.h View File

@@ -0,0 +1,58 @@
1
+#ifndef INIT_H
2
+#define INIT_H
3
+
4
+/*
5
+ * In order to avoid having objects dragged in just because main()
6
+ * calls their initialisation function, we allow each object to
7
+ * specify that it has a function that must be called to initialise
8
+ * that object.  The function call_init_fns() will call all the
9
+ * included objects' initialisation functions.
10
+ *
11
+ * Objects that require initialisation should include init.h and
12
+ * register the initialisation function using INIT_FN().
13
+ *
14
+ * Objects may register up to three functions: init, reset and exit.
15
+ * init gets called only once, at the point that Etherboot is
16
+ * initialised (before the call to main()).  reset gets called between
17
+ * each boot attempt.  exit gets called only once, just before the
18
+ * loaded OS starts up (or just before Etherboot exits, if it exits,
19
+ * or when the PXE NBP calls UNDI_SHUTDOWN, if it's a PXE NBP).
20
+ *
21
+ * The syntax is:
22
+ *   INIT_FN ( init_order, init_function, reset_function, exit_function );
23
+ * where init_order is an ordering taken from the list below.  Any
24
+ * function may be left as NULL.
25
+ */
26
+
27
+/* An entry in the initialisation function table */
28
+
29
+struct init_fn {
30
+	void ( *init ) ( void );
31
+	void ( *reset ) ( void );
32
+	void ( *exit ) ( void );
33
+};
34
+
35
+/* Use double digits to avoid problems with "10" < "9" on alphabetic sort */
36
+#define INIT_CONSOLE	"00"
37
+#define	INIT_CPU	"01"
38
+#define	INIT_TIMERS	"02"
39
+#define	INIT_PCMCIA	"03"
40
+#define	INIT_MEMSIZES	"04"
41
+#define	INIT_HEAP	"05"
42
+
43
+/* Macro for creating an initialisation function table entry */
44
+#define INIT_FN( init_order, init_func, reset_func, exit_func )		      \
45
+	static struct init_fn init_ ## init_func ## _ ## exit_func	      \
46
+	    __attribute__ ((used,__section__(".init_fns." init_order))) = {  \
47
+		.init = init_func,					      \
48
+		.reset = reset_func,					      \
49
+		.exit = exit_func,					      \
50
+	};
51
+
52
+/* Function prototypes */
53
+
54
+void call_init_fns ( void );
55
+void call_reset_fns ( void );
56
+void call_exit_fns ( void );
57
+
58
+#endif /* INIT_H */

+ 6
- 0
src/include/main.h View File

@@ -0,0 +1,6 @@
1
+#ifndef MAIN_H
2
+#define MAIN_H
3
+
4
+extern int main ( void );
5
+
6
+#endif /* MAIN_H */

+ 0
- 1
src/include/osdep.h View File

@@ -18,7 +18,6 @@
18 18
 #include "setjmp.h"
19 19
 #include "latch.h"
20 20
 #include "callbacks.h"
21
-#include "hooks.h"
22 21
 
23 22
 /* within 1MB of 4GB is too close. 
24 23
  * MAX_ADDR is the maximum address we can easily do DMA to.

+ 13
- 0
src/include/stddef.h View File

@@ -0,0 +1,13 @@
1
+#ifndef STDDEF_H
2
+#define STDDEF_H
3
+
4
+/* for size_t */
5
+#include "stdint.h"
6
+
7
+#undef NULL
8
+#define NULL	((void *)0)
9
+
10
+#undef offsetof
11
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
12
+
13
+#endif /* STDDEF_H */

+ 0
- 1
src/include/timer.h View File

@@ -53,7 +53,6 @@ extern void load_timer2(unsigned int ticks);
53 53
 extern inline int timer2_running(void);
54 54
 extern void waiton_timer2(unsigned int ticks);
55 55
 
56
-extern void setup_timers(void);
57 56
 extern void ndelay(unsigned int nsecs);
58 57
 extern void udelay(unsigned int usecs);
59 58
 extern void mdelay(unsigned int msecs);

+ 63
- 0
src/util/parserom.pl View File

@@ -0,0 +1,63 @@
1
+#!/usr/bin/perl -w
2
+#
3
+# Parse PCI_ROM and ISA_ROM entries from a source file on stdin and
4
+# output the relevant Makefile variable definitions to stdout
5
+#
6
+# Based upon portions of Ken Yap's genrules.pl
7
+
8
+use strict;
9
+use warnings;
10
+
11
+die "Syntax: $0 driver_source.c" unless @ARGV == 1;
12
+my $source = shift;
13
+open DRV, "<$source" or die "Could not open $source: $!\n";
14
+
15
+( my $family, my $driver_name ) = ( $source =~ /^(.*?([^\/]+))\..$/ )
16
+    or die "Could not parse source file name \"$source\"\n";
17
+
18
+my $printed_family;
19
+
20
+sub rom {
21
+  ( my $type, my $image, my $desc, my $vendor, my $device ) = @_;
22
+  my $ids = $vendor ? "$vendor,$device" : "-";
23
+  unless ( $printed_family ) {
24
+    print "\n";
25
+    print "# NIC\t\n";
26
+    print "# NIC\tfamily\t$family\n";
27
+    print "DRIVERS += $driver_name\n";
28
+    $printed_family = 1;
29
+  }
30
+  print "\n";
31
+  print "# NIC\t$image\t$ids\t$desc\n";
32
+  print "DRIVER_$image = $driver_name\n";
33
+  print "ROM_TYPE_$image = $type\n";
34
+  print "ROM_DESCRIPTION_$image = \"$desc\"\n";
35
+  print "PCI_VENDOR_$image = $vendor\n" if $vendor;
36
+  print "PCI_DEVICE_$image = $device\n" if $device;
37
+  print "ROMS += $image\n";
38
+  print "ROMS_$driver_name += $image\n";
39
+}
40
+
41
+while ( <DRV> ) {
42
+  next unless /(PCI|ISA)_ROM\s*\(/;
43
+
44
+  if ( /^\s*PCI_ROM\s*\(
45
+         \s*(0x[0-9A-Fa-f]{4})\s*, # PCI vendor
46
+         \s*(0x[0-9A-Fa-f]{4})\s*, # PCI device
47
+         \s*\"([^\"]*)\"\s*,	   # Image
48
+         \s*\"([^\"]*)\"\s*	   # Description
49
+       \)/x ) {
50
+    ( my $vendor, my $device, my $image, my $desc ) = ( lc $1, lc $2, $3, $4 );
51
+    rom ( "pci", $image, $desc, $vendor, $device );
52
+  } elsif ( /^\s*ISA_ROM\s*\(
53
+	      \s*\"([^\"]*)\"\s*,  # Image
54
+	      \s*\"([^\"]*)\"\s*   # Description
55
+	    \)/x ) {
56
+    ( my $image, my $desc ) = ( $1, $2 );
57
+    rom ( "isa", $image, $desc );
58
+  } else {
59
+    warn "Malformed PCI_ROM or ISA_ROM macro on line $. of $source\n";
60
+  }
61
+}
62
+
63
+close DRV;

+ 0
- 0
src/util/zfilelen.pl View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save