1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 FILE_LICENCE ( GPL2_OR_LATER );
20 
21 #include <gpxe/device.h>
22 #include <gpxe/init.h>
23 
24 /** @file
25  *
26  * Initialisation, startup and shutdown routines
27  *
28  */
29 
30 /** "startup() has been called" flag */
31 static int started = 0;
32 
33 /**
34  * Initialise gPXE
35  *
36  * This function performs the one-time-only and irreversible
37  * initialisation steps, such as initialising the heap.  It must be
38  * called before (almost) any other function.
39  *
40  * There is, by definition, no counterpart to this function on the
41  * shutdown path.
42  */
43 void initialise ( void ) {
44 	struct init_fn *init_fn;
45 
46 	/* Call registered initialisation functions */
47 	for_each_table_entry ( init_fn, INIT_FNS )
48 		init_fn->initialise ();
49 }
50 
51 /**
52  * Start up gPXE
53  *
54  * This function performs the repeatable initialisation steps, such as
55  * probing devices.  You may call startup() and shutdown() multiple
56  * times (as is done via the PXE API when PXENV_START_UNDI is used).
57  */
58 void startup ( void ) {
59 	struct startup_fn *startup_fn;
60 
61 	if ( started )
62 		return;
63 
64 	/* Call registered startup functions */
65 	for_each_table_entry ( startup_fn, STARTUP_FNS ) {
66 		if ( startup_fn->startup )
67 			startup_fn->startup();
68 	}
69 
70 	started = 1;
71 }
72 
73 /**
74  * Shut down gPXE
75  *
76  * @v flags		Shutdown behaviour flags
77  *
78  * This function reverses the actions of startup(), and leaves gPXE in
79  * a state ready to be removed from memory.  You may call startup()
80  * again after calling shutdown().
81  *
82  * Call this function only once, before either exiting main() or
83  * starting up a non-returnable image.
84  */
85 void shutdown ( int flags ) {
86 	struct startup_fn *startup_fn;
87 
88 	if ( ! started )
89 		return;
90 
91 	/* Call registered shutdown functions (in reverse order) */
92 	for_each_table_entry_reverse ( startup_fn, STARTUP_FNS ) {
93 		if ( startup_fn->shutdown )
94 			startup_fn->shutdown ( flags );
95 	}
96 
97 	started = 0;
98 }
99