wok-current view linld/stuff/src/HIMEM.CPP @ rev 19515

linld: multi initrd support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Nov 22 21:19:01 2016 +0100 (2016-11-22)
parents
children 7f92b23984dc
line source
1 // This file is distributed under GPL
2 //
3 // High mem handling routines
4 // C++ part of VCPI madness is here
6 #include "crtl.h"
7 #include "common.h"
9 // Returns physical addr of allocated himem chunk
10 // Never fails (will use fallback if not enough mem/no xmm)
11 // TODO: with proper cleanup it is possible to exit to DOS
12 // even after XMM alloc - do dealloc, then exit...
13 // don't forget to clean up the mess then, especially
14 // XMM handle which is lost inside xmm_alloc()...
15 // (don't drop fallback: use it if no XMM driver detected)
16 static void read2mem(struct image_himem *m) {
17 u32 buf=m->buf;
18 while(1) {
19 u8 xfer_buf[PAGE_SIZE];
20 u16 size = read_image(m, xfer_buf, sizeof(xfer_buf));
21 if(s16(size) <= 0) break;
22 memcpy32(0, buf, seg(xfer_buf), ofs(xfer_buf), size);
23 buf += size;
24 m->remaining -= size;
25 }
26 }
28 extern "C" void sort(u32* v, int size);
30 // Returns ptr to mallocated zero-terminated list of physical page addrs
31 // Never fails (will die if not enough mem)
32 // Addresses are sorted in ascending order
33 // static void malloc_vcpi(struct image_himem *m) {
34 static void read2vcpi(struct image_himem *m) {
35 u16 cnt = (m->size+PAGE_MASK)/PAGE_SIZE;
36 u32* bufv = (u32*)malloc_or_die((cnt+1)*sizeof(u32));
37 // our malloc zeroes allocated mem: buf[cnt]=0;
38 // Allocate pages, storing addrs in addrbuf
39 {for(int i=0;i<cnt;i++) {
40 u32 v;
41 asm {
42 db 66h
43 xor dx,dx
44 mov ax,0DE04h
45 int 67h
46 db 66h
47 mov [word ptr v],dx
48 }
49 extern const char vcpi_alloc_err[];
50 if(!v) die(vcpi_alloc_err);
51 bufv[i] = v;
52 }}
53 // Sanitize addresses: ascending sort
54 sort(bufv,cnt);
55 m->bufv = bufv;
56 //}
58 // Reads opened fd data into malloc_vcpi'ed memory
59 // Dies if file isn't exactly 'size' bytes long
60 // Needs intermediate buffer of exactly Nx4k bytes
61 // static void read2vcpi(struct image_himem *m) {
62 while(1) {
63 u8 xfer_buf[PAGE_SIZE];
64 u16 size = read_image(m, xfer_buf, PAGE_SIZE);
65 if(s16(size) <= 0 || !*bufv) break;
66 m->remaining -= size;
67 memcpy_vcpi(*bufv++, seg(xfer_buf), ofs(xfer_buf));
68 }
69 }
71 void init_vcpi() {
72 heap_top = prepare_vcpi(malloc_or_die(8*1024+4));
73 get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
74 }
76 int skip_xmmalloc;
77 void load_image(struct image_himem *m) {
78 no_exit++; // die() won't return to DOS
79 m->remaining = m->size;
80 m->buf = m->fallback;
81 if(m->fallback < _1m) {
82 read2mem(m);
83 } else if(vcpi==0) {
84 if (!skip_xmmalloc) {
85 u32 v = xmm_alloc(m->size);
86 if(v) m->buf = v;
87 }
88 read2mem(m);
89 } else {
90 //malloc_vcpi(m);
91 read2vcpi(m);
92 }
93 if(m->remaining) die("Read error");
94 //break iso case close(m->fd);
95 }