diff options
Diffstat (limited to 'arch/ppc/boot/openfirmware')
-rw-r--r-- | arch/ppc/boot/openfirmware/Makefile | 109 | ||||
-rw-r--r-- | arch/ppc/boot/openfirmware/chrpmain.c | 101 | ||||
-rw-r--r-- | arch/ppc/boot/openfirmware/common.c | 146 | ||||
-rw-r--r-- | arch/ppc/boot/openfirmware/dummy.c | 4 | ||||
-rw-r--r-- | arch/ppc/boot/openfirmware/misc.S | 67 | ||||
-rw-r--r-- | arch/ppc/boot/openfirmware/start.c | 172 |
6 files changed, 0 insertions, 599 deletions
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile deleted file mode 100644 index 66b739743759..000000000000 --- a/arch/ppc/boot/openfirmware/Makefile +++ /dev/null | |||
@@ -1,109 +0,0 @@ | |||
1 | # Makefile for making bootable images on various OpenFirmware machines. | ||
2 | # | ||
3 | # This file is included by the global makefile so that you can add your own | ||
4 | # architecture-specific flags and dependencies. | ||
5 | # | ||
6 | # Paul Mackerras January 1997 | ||
7 | # XCOFF bootable images for PowerMacs | ||
8 | # Geert Uytterhoeven September 1997 | ||
9 | # ELF bootable iamges for CHRP machines. | ||
10 | # Tom Rini January 2001 | ||
11 | # Cleaned up, moved into arch/ppc/boot/pmac | ||
12 | # Tom Rini July/August 2002 | ||
13 | # Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the | ||
14 | # rules. | ||
15 | |||
16 | zImage.initrd znetboot.initrd: del-ramdisk-sec := -R .ramdisk | ||
17 | zImage.initrd znetboot.initrd: initrd := .initrd | ||
18 | |||
19 | |||
20 | boot := arch/ppc/boot | ||
21 | common := $(boot)/common | ||
22 | utils := $(boot)/utils | ||
23 | bootlib := $(boot)/lib | ||
24 | of1275 := $(boot)/of1275 | ||
25 | images := $(boot)/images | ||
26 | |||
27 | CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000 | ||
28 | |||
29 | COMMONOBJS := start.o misc.o common.o | ||
30 | CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o | ||
31 | |||
32 | targets := $(CHRPOBJS) dummy.o | ||
33 | CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS)) | ||
34 | |||
35 | LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a | ||
36 | |||
37 | ifdef CONFIG_SMP | ||
38 | END := .smp | ||
39 | endif | ||
40 | ifdef CONFIG_PPC64BRIDGE | ||
41 | END += .64 | ||
42 | endif | ||
43 | |||
44 | |||
45 | $(images)/ramdisk.image.gz: | ||
46 | @echo ' MISSING $@' | ||
47 | @echo ' RAM disk image must be provided separately' | ||
48 | @/bin/false | ||
49 | |||
50 | quiet_cmd_genimage = GEN $@ | ||
51 | cmd_genimage = $(OBJCOPY) -R .comment \ | ||
52 | --add-section=.image=$(images)/vmlinux.gz \ | ||
53 | --set-section-flags=.image=contents,alloc,load,readonly,data $< $@ | ||
54 | |||
55 | targets += image.o | ||
56 | $(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE | ||
57 | $(call if_changed,genimage) | ||
58 | |||
59 | # Place the ramdisk in the initrd image. | ||
60 | quiet_cmd_genimage-initrd = GEN $@ | ||
61 | cmd_genimage-initrd = $(OBJCOPY) $< $@ \ | ||
62 | --add-section=.ramdisk=$(images)/ramdisk.image.gz \ | ||
63 | --set-section-flags=.ramdisk=contents,alloc,load,readonly,data | ||
64 | targets += image.initrd.o | ||
65 | $(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE | ||
66 | $(call if_changed,genimage-initrd) | ||
67 | |||
68 | |||
69 | targets += crt0.o | ||
70 | $(obj)/crt0.o: $(common)/crt0.S FORCE | ||
71 | $(call if_changed_dep,as_o_S) | ||
72 | |||
73 | quiet_cmd_gen-chrp = CHRP $@ | ||
74 | cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \ | ||
75 | $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) | ||
76 | |||
77 | $(images)/zImage.chrp: $(obj)/image.o $(CHRPOBJS) $(LIBS) \ | ||
78 | $(srctree)/$(boot)/ld.script | ||
79 | $(call cmd,gen-chrp) | ||
80 | $(images)/zImage.initrd.chrp: $(obj)/image.initrd.o $(CHRPOBJS) $(LIBS) \ | ||
81 | $(srctree)/$(boot)/ld.script | ||
82 | $(call cmd,gen-chrp) | ||
83 | |||
84 | quiet_cmd_addnote = ADDNOTE $@ | ||
85 | cmd_addnote = cat $< > $@ && $(utils)/addnote $@ | ||
86 | $(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \ | ||
87 | %-rs6k: % | ||
88 | $(call cmd,addnote) | ||
89 | |||
90 | # The targets used on the make command-line | ||
91 | |||
92 | PHONY += zImage zImage.initrd | ||
93 | zImage: $(images)/zImage.chrp \ | ||
94 | $(images)/zImage.chrp-rs6k | ||
95 | @echo ' kernel: $@ is ready ($<)' | ||
96 | zImage.initrd: $(images)/zImage.initrd.chrp \ | ||
97 | $(images)/zImage.initrd.chrp-rs6k | ||
98 | @echo ' kernel: $@ is ready ($<)' | ||
99 | |||
100 | TFTPIMAGE := /tftpboot/zImage | ||
101 | |||
102 | PHONY += znetboot znetboot.initrd | ||
103 | znetboot: $(images)/zImage.chrp | ||
104 | cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END) | ||
105 | @echo ' kernel: $@ is ready ($<)' | ||
106 | znetboot.initrd:$(images)/zImage.initrd.chrp | ||
107 | cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END) | ||
108 | @echo ' kernel: $@ is ready ($<)' | ||
109 | |||
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c deleted file mode 100644 index 245dbd9fc120..000000000000 --- a/arch/ppc/boot/openfirmware/chrpmain.c +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
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 | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <linux/string.h> | ||
10 | #include "nonstdio.h" | ||
11 | #include "of1275.h" | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/page.h> | ||
14 | |||
15 | /* Passed from the linker */ | ||
16 | extern char __image_begin, __image_end; | ||
17 | extern char __ramdisk_begin, __ramdisk_end; | ||
18 | extern char _start, _end; | ||
19 | |||
20 | extern unsigned int heap_max; | ||
21 | extern void flush_cache(void *, unsigned long); | ||
22 | extern void gunzip(void *, int, unsigned char *, int *); | ||
23 | extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
24 | unsigned int progend); | ||
25 | |||
26 | char *avail_ram; | ||
27 | char *begin_avail, *end_avail; | ||
28 | char *avail_high; | ||
29 | |||
30 | #define RAM_START 0x00000000 | ||
31 | #define RAM_END (64<<20) | ||
32 | |||
33 | #define BOOT_START ((unsigned long)_start) | ||
34 | #define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF) | ||
35 | |||
36 | #define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF) | ||
37 | #define PROG_START 0x00010000 | ||
38 | #define PROG_SIZE 0x007f0000 /* 8MB */ | ||
39 | |||
40 | #define SCRATCH_SIZE (128 << 10) | ||
41 | |||
42 | static char scratch[SCRATCH_SIZE]; /* 128k of scratch space for gunzip */ | ||
43 | |||
44 | typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); | ||
45 | |||
46 | void | ||
47 | boot(int a1, int a2, void *prom) | ||
48 | { | ||
49 | unsigned sa, len; | ||
50 | void *dst; | ||
51 | unsigned char *im; | ||
52 | unsigned int initrd_size, initrd_start; | ||
53 | |||
54 | printf("chrpboot starting: loaded at 0x%p\n\r", &_start); | ||
55 | |||
56 | initrd_size = &__ramdisk_end - &__ramdisk_begin; | ||
57 | if (initrd_size) { | ||
58 | initrd_start = (RAM_END - initrd_size) & ~0xFFF; | ||
59 | a1 = initrd_start; | ||
60 | a2 = initrd_size; | ||
61 | claim(initrd_start, RAM_END - initrd_start, 0); | ||
62 | printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", | ||
63 | initrd_start, &__ramdisk_begin, initrd_size); | ||
64 | memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size); | ||
65 | } else { | ||
66 | initrd_start = 0; | ||
67 | initrd_size = 0; | ||
68 | a2 = 0xdeadbeef; | ||
69 | } | ||
70 | |||
71 | im = &__image_begin; | ||
72 | len = &__image_end - &__image_begin; | ||
73 | /* claim 4MB starting at PROG_START */ | ||
74 | claim(PROG_START, PROG_SIZE - PROG_START, 0); | ||
75 | dst = (void *) PROG_START; | ||
76 | if (im[0] == 0x1f && im[1] == 0x8b) { | ||
77 | avail_ram = scratch; | ||
78 | begin_avail = avail_high = avail_ram; | ||
79 | end_avail = scratch + sizeof(scratch); | ||
80 | printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); | ||
81 | gunzip(dst, PROG_SIZE - PROG_START, im, &len); | ||
82 | printf("done %u bytes\n\r", len); | ||
83 | printf("%u bytes of heap consumed, max in use %u\n\r", | ||
84 | avail_high - begin_avail, heap_max); | ||
85 | } else { | ||
86 | memmove(dst, im, len); | ||
87 | } | ||
88 | |||
89 | flush_cache(dst, len); | ||
90 | make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp, | ||
91 | (PROG_START + PROG_SIZE)); | ||
92 | |||
93 | sa = PROG_START; | ||
94 | printf("start address = 0x%x\n\r", sa); | ||
95 | |||
96 | (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size); | ||
97 | |||
98 | printf("returned?\n\r"); | ||
99 | |||
100 | pause(); | ||
101 | } | ||
diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c deleted file mode 100644 index 0f46756a903e..000000000000 --- a/arch/ppc/boot/openfirmware/common.c +++ /dev/null | |||
@@ -1,146 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
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 | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include "nonstdio.h" | ||
11 | #include "of1275.h" | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/zlib.h> | ||
14 | #include <asm/bootinfo.h> | ||
15 | #include <asm/page.h> | ||
16 | |||
17 | /* Information from the linker */ | ||
18 | |||
19 | extern int strcmp(const char *s1, const char *s2); | ||
20 | extern char *avail_ram, *avail_high; | ||
21 | extern char *end_avail; | ||
22 | |||
23 | unsigned int heap_use, heap_max; | ||
24 | |||
25 | struct memchunk { | ||
26 | unsigned int size; | ||
27 | struct memchunk *next; | ||
28 | }; | ||
29 | |||
30 | static struct memchunk *freechunks; | ||
31 | |||
32 | static void *zalloc(unsigned size) | ||
33 | { | ||
34 | void *p; | ||
35 | struct memchunk **mpp, *mp; | ||
36 | |||
37 | size = (size + 7) & -8; | ||
38 | heap_use += size; | ||
39 | if (heap_use > heap_max) | ||
40 | heap_max = heap_use; | ||
41 | for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { | ||
42 | if (mp->size == size) { | ||
43 | *mpp = mp->next; | ||
44 | return mp; | ||
45 | } | ||
46 | } | ||
47 | p = avail_ram; | ||
48 | avail_ram += size; | ||
49 | if (avail_ram > avail_high) | ||
50 | avail_high = avail_ram; | ||
51 | if (avail_ram > end_avail) { | ||
52 | printf("oops... out of memory\n\r"); | ||
53 | pause(); | ||
54 | } | ||
55 | return p; | ||
56 | } | ||
57 | |||
58 | #define HEAD_CRC 2 | ||
59 | #define EXTRA_FIELD 4 | ||
60 | #define ORIG_NAME 8 | ||
61 | #define COMMENT 0x10 | ||
62 | #define RESERVED 0xe0 | ||
63 | |||
64 | void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) | ||
65 | { | ||
66 | z_stream s; | ||
67 | int r, i, flags; | ||
68 | |||
69 | /* skip header */ | ||
70 | i = 10; | ||
71 | flags = src[3]; | ||
72 | if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { | ||
73 | printf("bad gzipped data\n\r"); | ||
74 | exit(); | ||
75 | } | ||
76 | if ((flags & EXTRA_FIELD) != 0) | ||
77 | i = 12 + src[10] + (src[11] << 8); | ||
78 | if ((flags & ORIG_NAME) != 0) | ||
79 | while (src[i++] != 0) | ||
80 | ; | ||
81 | if ((flags & COMMENT) != 0) | ||
82 | while (src[i++] != 0) | ||
83 | ; | ||
84 | if ((flags & HEAD_CRC) != 0) | ||
85 | i += 2; | ||
86 | if (i >= *lenp) { | ||
87 | printf("gunzip: ran out of data in header\n\r"); | ||
88 | exit(); | ||
89 | } | ||
90 | |||
91 | /* Initialize ourself. */ | ||
92 | s.workspace = zalloc(zlib_inflate_workspacesize()); | ||
93 | r = zlib_inflateInit2(&s, -MAX_WBITS); | ||
94 | if (r != Z_OK) { | ||
95 | printf("zlib_inflateInit2 returned %d\n\r", r); | ||
96 | exit(); | ||
97 | } | ||
98 | s.next_in = src + i; | ||
99 | s.avail_in = *lenp - i; | ||
100 | s.next_out = dst; | ||
101 | s.avail_out = dstlen; | ||
102 | r = zlib_inflate(&s, Z_FINISH); | ||
103 | if (r != Z_OK && r != Z_STREAM_END) { | ||
104 | printf("inflate returned %d msg: %s\n\r", r, s.msg); | ||
105 | exit(); | ||
106 | } | ||
107 | *lenp = s.next_out - (unsigned char *) dst; | ||
108 | zlib_inflateEnd(&s); | ||
109 | } | ||
110 | |||
111 | /* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID, | ||
112 | * a machine type for BI_MACHTYPE, and the location where the end of the | ||
113 | * bootloader is (PROG_START + PROG_SIZE) | ||
114 | */ | ||
115 | void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | ||
116 | unsigned long progend) | ||
117 | { | ||
118 | struct bi_record *rec; | ||
119 | |||
120 | |||
121 | /* leave a 1MB gap then align to the next 1MB boundary */ | ||
122 | addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); | ||
123 | /* oldworld machine seem very unhappy about this. -- Tom */ | ||
124 | if (addr >= progend) | ||
125 | claim(addr, 0x1000, 0); | ||
126 | |||
127 | rec = (struct bi_record *)addr; | ||
128 | rec->tag = BI_FIRST; | ||
129 | rec->size = sizeof(struct bi_record); | ||
130 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
131 | |||
132 | rec->tag = BI_BOOTLOADER_ID; | ||
133 | sprintf( (char *)rec->data, name); | ||
134 | rec->size = sizeof(struct bi_record) + strlen(name) + 1; | ||
135 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
136 | |||
137 | rec->tag = BI_MACHTYPE; | ||
138 | rec->data[0] = mach; | ||
139 | rec->data[1] = 1; | ||
140 | rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); | ||
141 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
142 | |||
143 | rec->tag = BI_LAST; | ||
144 | rec->size = sizeof(struct bi_record); | ||
145 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
146 | } | ||
diff --git a/arch/ppc/boot/openfirmware/dummy.c b/arch/ppc/boot/openfirmware/dummy.c deleted file mode 100644 index 31dbf45bf99c..000000000000 --- a/arch/ppc/boot/openfirmware/dummy.c +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | int main(void) | ||
2 | { | ||
3 | return 0; | ||
4 | } | ||
diff --git a/arch/ppc/boot/openfirmware/misc.S b/arch/ppc/boot/openfirmware/misc.S deleted file mode 100644 index ab9e897cadd0..000000000000 --- a/arch/ppc/boot/openfirmware/misc.S +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
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 | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | .text | ||
10 | |||
11 | /* | ||
12 | * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to | ||
13 | * the address given as the 1st argument. | ||
14 | */ | ||
15 | .globl setup_bats | ||
16 | setup_bats: | ||
17 | mfpvr 5 | ||
18 | rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ | ||
19 | cmpwi 0,5,1 | ||
20 | li 0,0 | ||
21 | bne 4f | ||
22 | mtibatl 3,0 /* invalidate BAT first */ | ||
23 | ori 3,3,4 /* set up BAT registers for 601 */ | ||
24 | li 4,0x7f | ||
25 | mtibatu 2,3 | ||
26 | mtibatl 2,4 | ||
27 | oris 3,3,0x80 | ||
28 | oris 4,4,0x80 | ||
29 | mtibatu 3,3 | ||
30 | mtibatl 3,4 | ||
31 | b 5f | ||
32 | 4: mtdbatu 3,0 /* invalidate BATs first */ | ||
33 | mtibatu 3,0 | ||
34 | ori 3,3,0xff /* set up BAT registers for 604 */ | ||
35 | li 4,2 | ||
36 | mtdbatl 2,4 | ||
37 | mtdbatu 2,3 | ||
38 | mtibatl 2,4 | ||
39 | mtibatu 2,3 | ||
40 | oris 3,3,0x80 | ||
41 | oris 4,4,0x80 | ||
42 | mtdbatl 3,4 | ||
43 | mtdbatu 3,3 | ||
44 | mtibatl 3,4 | ||
45 | mtibatu 3,3 | ||
46 | 5: sync | ||
47 | isync | ||
48 | blr | ||
49 | |||
50 | /* | ||
51 | * Flush the dcache and invalidate the icache for a range of addresses. | ||
52 | * | ||
53 | * flush_cache(addr, len) | ||
54 | */ | ||
55 | .global flush_cache | ||
56 | flush_cache: | ||
57 | addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ | ||
58 | rlwinm. 4,4,27,5,31 | ||
59 | mtctr 4 | ||
60 | beqlr | ||
61 | 1: dcbf 0,3 | ||
62 | icbi 0,3 | ||
63 | addi 3,3,0x20 | ||
64 | bdnz 1b | ||
65 | sync | ||
66 | isync | ||
67 | blr | ||
diff --git a/arch/ppc/boot/openfirmware/start.c b/arch/ppc/boot/openfirmware/start.c deleted file mode 100644 index 1617a26956bf..000000000000 --- a/arch/ppc/boot/openfirmware/start.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
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 | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdarg.h> | ||
10 | #include "of1275.h" | ||
11 | |||
12 | extern int strlen(const char *s); | ||
13 | extern void boot(int a1, int a2, void *prom); | ||
14 | |||
15 | phandle stdin; | ||
16 | phandle stdout; | ||
17 | phandle stderr; | ||
18 | |||
19 | void printk(char *fmt, ...); | ||
20 | |||
21 | void | ||
22 | start(int a1, int a2, void *promptr) | ||
23 | { | ||
24 | ofinit(promptr); | ||
25 | if (ofstdio(&stdin, &stdout, &stderr)) | ||
26 | exit(); | ||
27 | |||
28 | boot(a1, a2, promptr); | ||
29 | for (;;) | ||
30 | exit(); | ||
31 | } | ||
32 | |||
33 | int writestring(void *f, char *ptr, int nb) | ||
34 | { | ||
35 | int w = 0, i; | ||
36 | char *ret = "\r"; | ||
37 | |||
38 | for (i = 0; i < nb; ++i) { | ||
39 | if (ptr[i] == '\n') { | ||
40 | if (i > w) { | ||
41 | write(f, ptr + w, i - w); | ||
42 | w = i; | ||
43 | } | ||
44 | write(f, ret, 1); | ||
45 | } | ||
46 | } | ||
47 | if (w < nb) | ||
48 | write(f, ptr + w, nb - w); | ||
49 | return nb; | ||
50 | } | ||
51 | |||
52 | int | ||
53 | putc(int c, void *f) | ||
54 | { | ||
55 | char ch = c; | ||
56 | |||
57 | return writestring(f, &ch, 1) == 1? c: -1; | ||
58 | } | ||
59 | |||
60 | int | ||
61 | putchar(int c) | ||
62 | { | ||
63 | return putc(c, stdout); | ||
64 | } | ||
65 | |||
66 | int | ||
67 | fputs(char *str, void *f) | ||
68 | { | ||
69 | int n = strlen(str); | ||
70 | |||
71 | return writestring(f, str, n) == n? 0: -1; | ||
72 | } | ||
73 | |||
74 | int | ||
75 | readchar(void) | ||
76 | { | ||
77 | char ch; | ||
78 | |||
79 | for (;;) { | ||
80 | switch (read(stdin, &ch, 1)) { | ||
81 | case 1: | ||
82 | return ch; | ||
83 | case -1: | ||
84 | printk("read(stdin) returned -1\n"); | ||
85 | return -1; | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static char line[256]; | ||
91 | static char *lineptr; | ||
92 | static int lineleft; | ||
93 | |||
94 | int | ||
95 | getchar(void) | ||
96 | { | ||
97 | int c; | ||
98 | |||
99 | if (lineleft == 0) { | ||
100 | lineptr = line; | ||
101 | for (;;) { | ||
102 | c = readchar(); | ||
103 | if (c == -1 || c == 4) | ||
104 | break; | ||
105 | if (c == '\r' || c == '\n') { | ||
106 | *lineptr++ = '\n'; | ||
107 | putchar('\n'); | ||
108 | break; | ||
109 | } | ||
110 | switch (c) { | ||
111 | case 0177: | ||
112 | case '\b': | ||
113 | if (lineptr > line) { | ||
114 | putchar('\b'); | ||
115 | putchar(' '); | ||
116 | putchar('\b'); | ||
117 | --lineptr; | ||
118 | } | ||
119 | break; | ||
120 | case 'U' & 0x1F: | ||
121 | while (lineptr > line) { | ||
122 | putchar('\b'); | ||
123 | putchar(' '); | ||
124 | putchar('\b'); | ||
125 | --lineptr; | ||
126 | } | ||
127 | break; | ||
128 | default: | ||
129 | if (lineptr >= &line[sizeof(line) - 1]) | ||
130 | putchar('\a'); | ||
131 | else { | ||
132 | putchar(c); | ||
133 | *lineptr++ = c; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | lineleft = lineptr - line; | ||
138 | lineptr = line; | ||
139 | } | ||
140 | if (lineleft == 0) | ||
141 | return -1; | ||
142 | --lineleft; | ||
143 | return *lineptr++; | ||
144 | } | ||
145 | |||
146 | extern int vsprintf(char *buf, const char *fmt, va_list args); | ||
147 | static char sprint_buf[1024]; | ||
148 | |||
149 | void | ||
150 | printk(char *fmt, ...) | ||
151 | { | ||
152 | va_list args; | ||
153 | int n; | ||
154 | |||
155 | va_start(args, fmt); | ||
156 | n = vsprintf(sprint_buf, fmt, args); | ||
157 | va_end(args); | ||
158 | writestring(stdout, sprint_buf, n); | ||
159 | } | ||
160 | |||
161 | int | ||
162 | printf(char *fmt, ...) | ||
163 | { | ||
164 | va_list args; | ||
165 | int n; | ||
166 | |||
167 | va_start(args, fmt); | ||
168 | n = vsprintf(sprint_buf, fmt, args); | ||
169 | va_end(args); | ||
170 | writestring(stdout, sprint_buf, n); | ||
171 | return n; | ||
172 | } | ||