Subversion Repositories Kolibri OS

Rev

Rev 9338 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9325 Boppan 1
#ifndef UMKA_H_INCLUDED
2
#define UMKA_H_INCLUDED
3
 
9337 Boppan 4
#include 
9325 Boppan 5
#include 
6
 
7
#define STDCALL __attribute__((__stdcall__))
8
 
9
#define BDFE_LEN_CP866 304
10
#define BDFE_LEN_UNICODE 560
11
 
9342 Boppan 12
#if defined(WIN32) || defined(_WIN32)
13
    typedef size_t off_t;
14
    typedef long ssize_t;
15
#   define PATH_MAX 256
16
#endif
17
 
9325 Boppan 18
typedef struct {
19
    uint32_t left, top, right, bottom;
20
} rect_t;
21
 
22
typedef struct {
23
    uint32_t left, top, width, height;
24
} box_t;
25
 
26
typedef struct {
27
    uint32_t dr0, dr1, dr2, dr3, dr7;
28
} dbg_regs_t;
29
 
30
typedef struct {
31
    uint32_t cpu_usage;
32
    uint16_t window_stack_position;
33
    uint16_t window_stack_value;
34
    uint16_t pad;
35
    char process_name[12];
36
    uint32_t memory_start;
37
    uint32_t used_memory;
38
    uint32_t pid;
39
    box_t box;
40
    uint16_t slot_state;
41
    uint16_t pad2;
42
    box_t client_box;
43
    uint8_t wnd_state;
44
    uint8_t pad3[1024-71];
45
} __attribute__((packed)) process_information_t;
46
 
47
_Static_assert(sizeof(process_information_t) == 0x400,
48
               "must be 0x400 bytes long");
49
 
50
typedef struct {
51
    box_t box;
52
    uint32_t cl_workarea;
53
    uint32_t cl_titlebar;
54
    uint32_t cl_frames;
55
    uint8_t z_modif;
56
    uint8_t fl_wstate;
57
    uint8_t fl_wdrawn;
58
    uint8_t fl_redraw;
59
} __attribute__((packed)) wdata_t;
60
 
61
_Static_assert(sizeof(wdata_t) == 0x20,
62
               "must be 0x20 bytes long");
63
 
64
typedef struct {
65
    uint32_t frame;
66
    uint32_t grab;
67
    uint32_t work_3d_dark;
68
    uint32_t work_3d_light;
69
    uint32_t grab_text;
70
    uint32_t work;
71
    uint32_t work_button;
72
    uint32_t work_button_text;
73
    uint32_t work_text;
74
    uint32_t work_graph;
75
} system_colors_t;
76
 
77
typedef enum {
78
    DEFAULT_ENCODING,
79
    CP866,
80
    UTF16,
81
    UTF8,
82
    INVALID_ENCODING,
83
} fs_enc_t;
84
 
85
typedef enum {
86
    F70 = 70,
87
    F80 = 80,
88
} f70or80_t;
89
 
90
enum {
91
    ERROR_SUCCESS,
92
    ERROR_DISK_BASE,
93
    ERROR_UNSUPPORTED_FS,
94
    ERROR_UNKNOWN_FS,
95
    ERROR_PARTITION,
96
    ERROR_FILE_NOT_FOUND,
97
    ERROR_END_OF_FILE,
98
    ERROR_MEMORY_POINTER,
99
    ERROR_DISK_FULL,
100
    ERROR_FS_FAIL,
101
    ERROR_ACCESS_DENIED,
102
    ERROR_DEVICE,
103
    ERROR_OUT_OF_MEMORY,
104
};
105
 
106
typedef struct lhead lhead_t;
107
 
108
struct lhead {
109
    lhead_t *next;
110
    lhead_t *prev;
111
};
112
 
113
typedef struct {
114
    lhead_t  wait_list;
115
    uint32_t count;
116
} mutex_t;
117
 
118
typedef mutex_t rwsem_t;
119
 
120
typedef struct {
121
    uint32_t flags;
122
    uint32_t sector_size;
123
    uint64_t capacity;  // in sectors
124
} diskmediainfo_t;
125
 
126
typedef struct {
127
    uintptr_t   pointer;
128
    uint32_t    data_size;
129
    uintptr_t   data;
130
    uint32_t    sad_size;
131
    uint32_t    search_start;
132
    uint32_t    sector_size_log;
133
} disk_cache_t;
134
 
135
typedef struct {
136
    uint64_t first_sector;
137
    uint64_t length;    // in sectors
138
    void *disk;
139
    void *fs_user_functions;
140
} partition_t;
141
 
142
typedef struct disk_t disk_t;
143
 
144
typedef struct {
145
    uint32_t  strucsize;
146
    STDCALL void (*close)(void *userdata);
147
    STDCALL void (*closemedia)(void *userdata);
148
    STDCALL int (*querymedia)(void *userdata, diskmediainfo_t *info);
149
    STDCALL int (*read)(void *userdata, void *buffer, off_t startsector,
150
                        size_t *numsectors);
151
    STDCALL int (*write)(void *userdata, void *buffer, off_t startsector,
152
                         size_t *numsectors);
153
    STDCALL int (*flush)(void *userdata);
154
    STDCALL unsigned int (*adjust_cache_size)(void *userdata,
155
                                              size_t suggested_size);
156
} diskfunc_t;
157
 
158
struct disk_t {
159
    disk_t *next;
160
    disk_t *prev;
161
    diskfunc_t *functions;
162
    const char *name;
163
    void *userdata;
164
    uint32_t driver_flags;
165
    uint32_t ref_count;
166
    mutex_t media_lock;
167
    uint8_t media_inserted;
168
    uint8_t media_used;
169
    uint16_t padding;
170
    uint32_t media_ref_count;
171
    diskmediainfo_t media_info;
172
    uint32_t num_partitions;
173
    partition_t **partitions;
174
    uint32_t cache_size;
175
    mutex_t cache_lock;
176
    disk_cache_t sys_cache;
177
    disk_cache_t app_cache;
178
};
179
 
180
typedef struct {
181
    uint32_t attr;
182
    uint32_t enc;
183
    uint32_t ctime;
184
    uint32_t cdate;
185
    uint32_t atime;
186
    uint32_t adate;
187
    uint32_t mtime;
188
    uint32_t mdate;
189
    uint64_t size;
190
    char name[0x7777];  // how to handle this properly? FIXME
191
} bdfe_t;
192
 
193
typedef struct {
194
    int32_t status;
195
    uint32_t count;
196
} f7080ret_t;
197
 
198
typedef struct {
199
    uint32_t sf;
200
    uint64_t offset;
201
    uint32_t count;
202
    void *buf;
203
    union {
204
        struct {
205
            uint8_t zero;
206
            const char *path;
207
        } __attribute__((packed)) f70;
208
        struct {
209
            uint32_t path_encoding;
210
            const char *path;
211
        } f80;
212
    } u;
213
} __attribute__((packed)) f7080s0arg_t;
214
 
215
typedef struct {
216
    uint32_t sf;
217
    uint32_t offset;
218
    uint32_t encoding;
219
    uint32_t size;
220
    void *buf;
221
    union {
222
        struct {
223
            uint8_t zero;
224
            const char *path;
225
        } __attribute__((packed)) f70;
226
        struct {
227
            uint32_t path_encoding;
228
            const char *path;
229
        } f80;
230
    } u;
231
} __attribute__((packed)) f7080s1arg_t;
232
 
233
typedef struct {
234
    uint32_t version;
235
    uint32_t cnt;
236
    uint32_t total_cnt;
237
    uint32_t zeroed[5];
238
    bdfe_t bdfes[];
239
} f7080s1info_t;
240
 
241
typedef struct {
242
    uint32_t sf;
243
    uint32_t reserved1;
244
    uint32_t flags;
245
    uint32_t reserved2;
246
    void *buf;
247
    union {
248
        struct {
249
            uint8_t zero;
250
            const char *path;
251
        } __attribute__((packed)) f70;
252
        struct {
253
            uint32_t path_encoding;
254
            const char *path;
255
        } f80;
256
    } u;
257
} __attribute__((packed)) f7080s5arg_t;
258
 
259
typedef struct {
260
    uint32_t sf;
261
    uint32_t flags;
262
    char *params;
263
    uint32_t reserved1;
264
    uint32_t reserved2;
265
    union {
266
        struct {
267
            uint8_t zero;
268
            const char *path;
269
        } __attribute__((packed)) f70;
270
        struct {
271
            uint32_t path_encoding;
272
            const char *path;
273
        } f80;
274
    } u;
275
} __attribute__((packed)) f7080s7arg_t;
276
 
277
#define KF_READONLY 0x01
278
#define KF_HIDDEN   0x02
279
#define KF_SYSTEM   0x04
280
#define KF_LABEL    0x08
281
#define KF_FOLDER   0x10
282
#define KF_ATTR_CNT 5
283
 
284
#define HASH_SIZE 32
285
typedef struct {
286
    uint8_t hash[HASH_SIZE];
287
    uint8_t opaque[1024-HASH_SIZE];
288
} hash_context;
289
 
290
typedef struct {
291
    uint32_t edi;
292
    uint32_t esi;
293
    uint32_t ebp;
294
    uint32_t esp;
295
    uint32_t ebx;
296
    uint32_t edx;
297
    uint32_t ecx;
298
    uint32_t eax;
299
} pushad_t;
300
 
301
#define NET_TYPE_ETH  1
302
#define NET_TYPE_SLIP 2
303
 
304
// Link state
305
#define ETH_LINK_DOWN    0x0    // Link is down
306
#define ETH_LINK_UNKNOWN 0x1    // There could be an active link
307
#define ETH_LINK_FD      0x2    // full duplex flag
308
#define ETH_LINK_10M     0x4    // 10 mbit
309
#define ETH_LINK_100M    0x8    // 100 mbit
310
#define ETH_LINK_1G      0xc    // gigabit
311
 
312
// Ethernet protocol numbers
313
#define ETHER_PROTO_ARP           0x0608
314
#define ETHER_PROTO_IPv4          0x0008
315
#define ETHER_PROTO_IPv6          0xDD86
316
#define ETHER_PROTO_PPP_DISCOVERY 0x6388
317
#define ETHER_PROTO_PPP_SESSION   0x6488
318
 
319
// Internet protocol numbers
320
#define IP_PROTO_IP   0
321
#define IP_PROTO_ICMP 1
322
#define IP_PROTO_TCP  6
323
#define IP_PROTO_UDP  17
324
#define IP_PROTO_RAW  255
325
 
326
// IP options
327
#define IP_TOS     1
328
#define IP_TTL     2
329
#define IP_HDRINCL 3
330
 
331
// PPP protocol numbers
332
#define PPP_PROTO_IPv4     0x2100
333
#define PPP_PROTO_IPV6     0x5780
334
#define PPP_PROTO_ETHERNET 666
335
 
336
// Protocol family
337
#define AF_INET4  AF_INET
338
 
339
typedef struct net_device_t net_device_t;
340
 
341
typedef struct {
342
        void *next;     // pointer to next frame in list
343
        void *prev;     // pointer to previous frame in list
344
        net_device_t *device;   // ptr to NET_DEVICE structure
345
        uint32_t type;  // encapsulation type: e.g. Ethernet
346
        size_t length;  // size of encapsulated data
347
        size_t offset;  // offset to actual data (24 bytes for default frame)
348
        uint8_t data[];
349
} net_buff_t;
350
 
351
struct net_device_t {
352
    uint32_t device_type;   // type field
353
    uint32_t mtu;           // Maximal Transmission Unit
354
    char *name;             // ptr to 0 terminated string
355
 
356
    // ptrs to driver functions
357
    STDCALL void (*unload) (void);
358
    STDCALL void (*reset) (void);
359
    STDCALL int (*transmit) (net_buff_t *);
360
 
361
    uint64_t bytes_tx;      // statistics, updated by the driver
362
    uint64_t bytes_rx;
363
    uint32_t packets_tx;
364
    uint32_t packets_rx;
365
 
366
    uint32_t link_state;    // link state (0 = no link)
367
    uint32_t hwacc;         // bitmask stating enabled HW accelerations (offload
368
                            // engines)
369
    uint8_t mac[6];
370
    void *userdata;         // not in kolibri, umka-specific
371
}; // NET_DEVICE
372
 
373
typedef struct {
374
    uint32_t ip;
375
    uint8_t mac[6];
376
    uint16_t status;
377
    uint16_t ttl;
378
} arp_entry_t;
379
 
380
typedef struct acpi_node acpi_node_t;
381
struct acpi_node {
382
    uint32_t name;
383
    int32_t refcount;
384
    acpi_node_t *parent;
385
    acpi_node_t *children;
386
    acpi_node_t *next;
387
    int32_t type;
388
};
389
 
390
typedef struct {
391
    acpi_node_t node;
392
    uint64_t value;
393
} kos_node_integer_t;
394
 
395
typedef struct {
396
    acpi_node_t node;
397
    acpi_node_t **list;
398
    size_t el_cnt;
399
} kos_node_package_t;
400
 
401
__attribute__((__noreturn__)) void
402
kos_osloop(void);
403
 
404
void
9337 Boppan 405
irq0(int signo, void *info_unused, void *context);
9325 Boppan 406
 
407
void
408
umka_init(void);
409
 
410
void
411
i40(void);
412
 
413
uint32_t
414
kos_time_to_epoch(uint32_t *time);
415
 
416
STDCALL disk_t *
417
disk_add(diskfunc_t *disk, const char *name, void *userdata, uint32_t flags);
418
 
419
STDCALL void *
420
disk_media_changed(diskfunc_t *disk, int inserted);
421
 
422
STDCALL void
423
disk_del(disk_t *disk);
424
 
425
void
426
hash_oneshot(void *ctx, void *data, size_t len);
427
 
428
extern uint8_t xfs_user_functions[];
429
extern uint8_t ext_user_functions[];
430
extern uint8_t fat_user_functions[];
431
extern uint8_t ntfs_user_functions[];
432
 
433
extern uint8_t kos_ramdisk[2880*512];
434
 
435
disk_t *
436
kos_ramdisk_init(void);
437
 
438
STDCALL void
439
kos_set_mouse_data(uint32_t btn_state, int32_t xmoving, int32_t ymoving,
440
                   int32_t vscroll, int32_t hscroll);
441
 
442
static inline void
443
umka_mouse_move(int lbheld, int mbheld, int rbheld, int xabs, int32_t xmoving,
444
                int yabs, int32_t ymoving, int32_t hscroll, int32_t vscroll) {
445
    uint32_t btn_state = lbheld + (rbheld << 1) + (mbheld << 2) +
446
                         (yabs << 30) + (xabs << 31);
447
    kos_set_mouse_data(btn_state, xmoving, ymoving, vscroll, hscroll);
448
}
449
 
450
STDCALL net_buff_t *
451
kos_net_buff_alloc(size_t size);
452
 
453
static inline size_t
454
umka_new_sys_threads(uint32_t flags, void (*entry)(), void *stack) {
455
    size_t tid;
456
    __asm__ __inline__ __volatile__ (
9338 Boppan 457
        "push %%ebx;"
458
        "push %%esi;"
459
        "push %%edi;"
9325 Boppan 460
        "call   kos_new_sys_threads;"
9338 Boppan 461
        "pop %%edi;"
462
        "pop %%esi;"
463
        "pop %%ebx"
9325 Boppan 464
        : "=a"(tid)
465
        : "b"(flags),
466
          "c"(entry),
467
          "d"(stack)
468
        : "memory", "cc");
469
    return tid;
470
}
471
 
472
static inline void
473
kos_acpi_call_name(void *ctx, const char *name) {
474
    __asm__ __inline__ __volatile__ (
475
        "pushad;"
476
        "push   %[name];"
477
        "push   %[ctx];"
478
        "call   acpi.call_name;"
479
        "popad"
480
        :
481
        : [ctx] "r"(ctx), [name] "r"(name)
482
        : "memory", "cc");
483
}
484
 
485
#define KOS_ACPI_NODE_Uninitialized 1
486
#define KOS_ACPI_NODE_Integer       2
487
#define KOS_ACPI_NODE_String        3
488
#define KOS_ACPI_NODE_Buffer        4
489
#define KOS_ACPI_NODE_Package       5
490
#define KOS_ACPI_NODE_OpRegionField 6
491
#define KOS_ACPI_NODE_IndexField    7
492
#define KOS_ACPI_NODE_BankField     8
493
#define KOS_ACPI_NODE_Device        9
494
 
495
extern acpi_node_t *kos_acpi_root;
496
 
497
typedef struct {
498
    int pew[0x100];
499
} amlctx_t;
500
 
501
struct pci_dev {
502
    struct pci_dev *next;
503
    size_t bus;
504
    size_t dev;
505
    size_t fun;
506
    void *acpi;
507
    struct pci_dev *children;
508
    struct pci_dev *parent;
509
    void *prt;
510
    size_t is_bridge;
511
    size_t vendor_id;
512
    size_t device_id;
513
    size_t int_pin;
514
    size_t gsi;
515
};
516
 
517
extern struct pci_dev *kos_pci_root;
518
 
519
void
520
kos_acpi_aml_init();
521
 
522
STDCALL void
523
kos_aml_attach(acpi_node_t *parent, acpi_node_t *node);
524
 
525
STDCALL void
526
kos_acpi_fill_pci_irqs(void *ctx);
527
 
528
STDCALL amlctx_t*
529
kos_acpi_aml_new_thread();
530
 
531
STDCALL acpi_node_t*
532
kos_aml_alloc_node(int32_t type);
533
 
534
STDCALL acpi_node_t*
535
kos_aml_constructor_integer(void);
536
 
537
STDCALL acpi_node_t*
538
kos_aml_constructor_package(size_t el_cnt);
539
 
540
STDCALL acpi_node_t*
541
kos_acpi_lookup_node(acpi_node_t *root, char *name);
542
 
543
STDCALL void
544
kos_acpi_print_tree(void *ctx);
545
 
546
#define MAX_PCI_DEVICES 256
547
 
548
extern void *kos_acpi_dev_data;
549
extern size_t kos_acpi_dev_size;
550
extern void *kos_acpi_dev_next;
551
 
552
STDCALL void*
553
kos_kernel_alloc(size_t len);
554
 
555
STDCALL void
556
kos_pci_walk_tree(struct pci_dev *node,
557
                  STDCALL void* (*test)(struct pci_dev *node, void *arg),
558
                  STDCALL void* (*clbk)(struct pci_dev *node, void *arg),
559
                  void *arg);
560
 
561
typedef struct {
562
    uint32_t value;
563
    uint32_t errorcode;
564
} f75ret_t;
565
 
566
typedef struct {
567
    uint32_t eax;
568
    uint32_t ebx;
569
} f76ret_t;
570
 
571
static inline void
572
umka_stack_init() {
573
    __asm__ __inline__ __volatile__ (
574
        "pushad;"
575
        "call   kos_stack_init;"
576
        "popad"
577
        :
578
        :
579
        : "memory", "cc");
580
}
581
 
582
static inline int32_t
583
kos_net_add_device(net_device_t *dev) {
584
    int32_t dev_num;
585
    __asm__ __inline__ __volatile__ (
586
        "call   net_add_device"
587
        : "=a"(dev_num)
588
        : "b"(dev)
589
        : "ecx", "edx", "esi", "edi", "memory", "cc");
590
 
591
    return dev_num;
592
}
593
 
594
STDCALL void
595
kos_window_set_screen(ssize_t left, ssize_t top, ssize_t right, ssize_t bottom,
596
                      ssize_t proc);
597
 
598
typedef struct {
599
    int32_t x;
600
    int32_t y;
601
    size_t width;
602
    size_t height;
603
    size_t bits_per_pixel;
604
    size_t vrefresh;
605
    void *current_lfb;
606
    size_t lfb_pitch;
607
 
608
    rwsem_t win_map_lock;
609
    uint8_t *win_map;
610
    size_t win_map_pitch;
611
    size_t win_map_size;
612
 
613
    void *modes;
614
    void *ddev;
615
    void *connector;
616
    void *crtc;
617
 
618
    void *cr_list_next;
619
    void *cr_list_prev;
620
 
621
    void *cursor;
622
 
623
    void *init_cursor;
624
    void *select_cursor;
625
    void *show_cursor;
626
    void *move_cursor;
627
    void *restore_cursor;
628
    void *disable_mouse;
629
    size_t mask_seqno;
630
    void *check_mouse;
631
    void *check_m_pixel;
632
 
633
    size_t bytes_per_pixel;
634
} __attribute__((packed)) display_t;
635
 
636
extern display_t kos_display;
637
 
638
typedef struct {
639
    uint64_t addr;
640
    uint64_t size;
641
    uint32_t type;
642
} e820entry_t;
643
 
644
#define MAX_MEMMAP_BLOCKS 32
645
 
646
typedef struct {
647
    uint8_t bpp;    // bits per pixel
648
    uint16_t pitch; // scanline length
649
    uint8_t pad1[5];
650
    uint16_t vesa_mode;
651
    uint16_t x_res;
652
    uint16_t y_res;
653
    uint8_t pad2[6];
654
    uint32_t bank_switch;   // Vesa 1.2 pm bank switch
655
    void *lfb;  // Vesa 2.0 LFB address
656
    uint8_t mtrr;   // 0 or 1: enable MTRR graphics acceleration
657
    uint8_t launcher_start; // 0 or 1: start the first app (right now it's
658
                            // LAUNCHER) after kernel is loaded
659
    uint8_t debug_print;    // if nonzero, duplicates debug output to the screen
660
    uint8_t dma;    // DMA write: 1=yes, 2=no
661
    uint8_t pci_data[8];
662
    uint8_t pad3[8];
663
    uint8_t shutdown_type;  // see sysfn 18.9
664
    uint8_t pad4[15];
665
    uint32_t apm_entry; // entry point of APM BIOS
666
    uint16_t apm_version;   // BCD
667
    uint16_t apm_flags;
668
    uint8_t pad5[8];
669
    uint16_t apm_code_32;
670
    uint16_t apm_code_16;
671
    uint16_t apm_data_16;
672
    uint8_t rd_load_from;   // Device to load ramdisk from, RD_LOAD_FROM_*
673
    uint8_t pad6[1];
674
    uint16_t kernel_restart;
675
    uint16_t sys_disk;  // Device to mount on /sys/, see loader_doc.txt for details
676
    void *acpi_rsdp;
677
    char syspath[0x17];
678
    void *devicesdat_data;
679
    size_t devicesdat_size;
680
    uint8_t bios_hd_cnt;    // number of BIOS hard disks
681
    uint8_t bios_hd[0x80];  // BIOS hard disks
682
    size_t memmap_block_cnt;    // available physical memory map: number of blocks
683
    e820entry_t memmap_blocks[MAX_MEMMAP_BLOCKS];
684
    uint8_t acpi_usage;
685
} __attribute__((packed)) boot_data_t;
686
 
687
extern boot_data_t kos_boot;
688
 
689
void
690
umka_cli(void);
691
 
692
void
693
umka_sti(void);
694
 
695
extern uint8_t coverage_begin[];
696
extern uint8_t coverage_end[];
697
 
698
typedef struct appobj_t appobj_t;
699
 
700
struct appobj_t {
701
    uint32_t magic;
702
    void *destroy;  // internal destructor
703
    appobj_t *fd;   // next object in list
704
    appobj_t *bk;   // prev object in list
705
    uint32_t pid;   // owner id
706
};
707
 
708
typedef struct {
709
    uint32_t magic;
710
    void *destroy;  // internal destructor
711
    appobj_t *fd;   // next object in list
712
    appobj_t *bk;   // prev object in list
713
    uint32_t pid;   // owner id
714
    uint32_t id;    // event uid
715
    uint32_t state; // internal flags
716
    uint32_t code;
717
    uint32_t pad[5];
718
} event_t;
719
 
720
typedef struct {
721
    lhead_t list;
722
    lhead_t thr_list;
723
    mutex_t heap_lock;
724
    void *heap_base;
725
    void *heap_top;
726
    uint32_t mem_used;
727
    void *dlls_list_ptr;
728
    void *pdt_0_phys;
729
    void *pdt_1_phys;
730
    void *io_map_0;
731
    void *io_map_1;
732
 
733
    void *ht_lock;
734
    void *ht_free;
735
    void *ht_next;
736
    void *htab[(1024-18*4)/4];
737
    void *pdt_0[1024];
738
} proc_t;
739
 
740
_Static_assert(sizeof(proc_t) == 0x1400, "must be 0x1400 bytes long");
741
 
742
typedef struct {
743
    char app_name[11];
744
    uint8_t pad1[5];
745
 
746
    lhead_t list;                  // +16
747
    proc_t *process;               // +24
748
    void *fpu_state;               // +28
749
    void *exc_handler;             // +32
750
    uint32_t except_mask;          // +36
751
    void *pl0_stack;               // +40
752
    void *cursor;                  // +44
753
    event_t *fd_ev;                // +48
754
    event_t *bk_ev;                // +52
755
    appobj_t *fd_obj;              // +56
756
    appobj_t *bk_obj;              // +60
757
    void *saved_esp;               // +64
758
    uint32_t io_map[2];            // +68
759
    uint32_t dbg_state;            // +76
760
    char *cur_dir;                 // +80
761
    uint32_t wait_timeout;         // +84
762
    uint32_t saved_esp0;           // +88
763
    uint32_t wait_begin;           // +92
764
    int (*wait_test)(void);        // +96
765
    void *wait_param;              // +100
766
    void *tls_base;                // +104
767
    uint32_t event_mask;           // +108
768
    uint32_t tid;                  // +112
769
    uint32_t draw_bgr_x;           // +116
770
    uint32_t draw_bgr_y;           // +120
771
    uint8_t state;                 // +124
772
    uint8_t pad2[3];               // +125
773
    uint8_t *wnd_shape;            // +128
774
    uint32_t wnd_shape_scale;      // +132
775
    uint32_t mem_start;            // +136
776
    uint32_t counter_sum;          // +140
777
    box_t saved_box;               // +144
778
    uint32_t *ipc_start;           // +160
779
    size_t ipc_size;               // +164
780
    uint32_t occurred_events;      // +168
781
    uint32_t debugger_slot;        // +172
782
    uint32_t terminate_protection; // +176
783
    uint8_t keyboard_mode;         // +180
784
    uint8_t captionEncoding;       // +181
785
    uint8_t pad3[2];               // +182
786
    char *exec_params;             // +184
787
    void *dbg_event_mem;           // +188
788
    dbg_regs_t dbg_regs;           // +192
789
    char *wnd_caption;             // +212
790
    box_t wnd_clientbox;           // +216
791
    uint32_t priority;             // +232
792
    lhead_t in_schedule;           // +236
793
    uint32_t counter_add;          // +244
794
    uint32_t cpu_usage;            // +248
795
    uint32_t pad4;                 // +252
796
} appdata_t;
797
 
798
_Static_assert(sizeof(appdata_t) == 256, "must be 0x100 bytes long");
799
 
800
typedef struct {
801
    uint32_t event_mask;
802
    uint32_t pid;
803
    uint16_t pad1;
804
    uint8_t state;
805
    uint8_t pad2;
806
    uint16_t pad3;
807
    uint8_t wnd_number;
808
    uint8_t pad4;
809
    uint32_t mem_start;
810
    uint32_t counter_sum;
811
    uint32_t counter_add;
812
    uint32_t cpu_usage;
813
} taskdata_t;
814
 
815
_Static_assert(sizeof(taskdata_t) == 32, "must be 0x20 bytes long");
816
 
817
#define UMKA_SHELL 1u
818
#define UMKA_FUSE  2u
819
#define UMKA_OS    3u
820
 
821
#define MAX_PRIORITY    0 // highest, used for kernel tasks
822
#define USER_PRIORITY   1 // default
823
#define IDLE_PRIORITY   2 // lowest, only IDLE thread goes here
824
#define NR_SCHED_QUEUES 3 // MUST equal IDLE_PRIORYTY + 1
825
 
826
extern appdata_t *kos_scheduler_current[NR_SCHED_QUEUES];
827
 
828
extern uint32_t umka_tool;
829
extern uint32_t umka_initialized;
830
extern uint8_t kos_redraw_background;
831
extern size_t kos_task_count;
832
extern taskdata_t *kos_task_base;
833
extern wdata_t kos_window_data[];
834
extern taskdata_t kos_task_table[];
835
extern appdata_t kos_slot_base[];
836
extern uint32_t kos_current_process;
837
extern appdata_t *kos_current_slot;
838
extern uint32_t kos_current_slot_idx;
839
extern void umka_do_change_task(appdata_t *new);
840
extern void scheduler_add_thread(void);
841
extern void find_next_task(void);
842
extern uint8_t kos_lfb_base[];
843
extern uint16_t kos_win_stack[];
844
extern uint16_t kos_win_pos[];
845
extern uint32_t kos_acpi_ssdt_cnt;
846
extern uint8_t *kos_acpi_ssdt_base[];
847
extern size_t kos_acpi_ssdt_size[];
848
extern void *acpi_ctx;
849
extern uint32_t kos_acpi_usage;
850
extern uint32_t kos_acpi_node_alloc_cnt;
851
extern uint32_t kos_acpi_node_free_cnt;
852
extern uint32_t kos_acpi_count_nodes(void *ctx) STDCALL;
853
extern disk_t disk_list;
854
 
855
static inline void
856
umka_scheduler_add_thread(appdata_t *thread, int32_t priority) {
857
    __asm__ __inline__ __volatile__ (
858
        "call   do_change_thread"
859
        :
860
        : "c"(priority),
861
          "d"(thread)
862
        : "memory", "cc");
863
 
864
}
865
 
866
#define MAX_PRIORITY    0
867
#define USER_PRIORITY   1
868
#define IDLE_PRIORITY   2
869
#define NR_SCHED_QUEUES 3
870
 
871
#define SCHEDULE_ANY_PRIORITY 0
872
#define SCHEDULE_HIGHER_PRIORITY 1
873
 
874
typedef struct {
875
    appdata_t *appdata;
876
    taskdata_t *taskdata;
877
    int same;
878
} find_next_task_t;
879
 
880
static inline find_next_task_t
881
umka_find_next_task(int32_t priority) {
882
    find_next_task_t fnt;
883
    __asm__ __inline__ __volatile__ (
884
        "call   find_next_task;"
9338 Boppan 885
        "setz   %%al;"
886
        "movzx  %%eax, %%al"
9325 Boppan 887
        : "=b"(fnt.appdata),
888
          "=D"(fnt.taskdata),
889
          "=a"(fnt.same)
890
        : "b"(priority)
891
        : "memory", "cc");
892
    return fnt;
893
}
894
 
895
static inline void
896
umka_i40(pushad_t *regs) {
897
    __asm__ __inline__ __volatile__ (
9338 Boppan 898
        "push   %%ebp;"
899
        "mov    %%ebp, %[ebp];"
9325 Boppan 900
        "call   i40;"
9338 Boppan 901
        "pop    %%ebp"
9325 Boppan 902
        : "=a"(regs->eax),
903
          "=b"(regs->ebx)
904
        : "a"(regs->eax),
905
          "b"(regs->ebx),
906
          "c"(regs->ecx),
907
          "d"(regs->edx),
908
          "S"(regs->esi),
909
          "D"(regs->edi),
910
          [ebp] "Rm"(regs->ebp)
911
        : "memory");
912
}
913
 
914
static inline void
915
umka_sys_draw_window(size_t x, size_t xsize, size_t y, size_t ysize,
916
                     uint32_t color, int has_caption, int client_relative,
917
                     int fill_workarea, int gradient_fill, int movable,
918
                     uint32_t style, const char *caption) {
919
    __asm__ __inline__ __volatile__ (
920
        "call   i40"
921
        :
922
        : "a"(0),
923
          "b"((x << 16) + xsize),
924
          "c"((y << 16) + ysize),
925
          "d"((gradient_fill << 31) + (!fill_workarea << 30)
926
              + (client_relative << 29) + (has_caption << 28) + (style << 24)
927
              + color),
928
          "S"(!movable << 24),
929
          "D"(caption)
930
        : "memory");
931
}
932
 
933
static inline void
934
umka_sys_set_pixel(size_t x, size_t y, uint32_t color, int invert) {
935
    __asm__ __inline__ __volatile__ (
936
        "call   i40"
937
        :
938
        : "a"(1),
939
          "b"(x),
940
          "c"(y),
941
          "d"((invert << 24) + color)
942
        : "memory");
943
}
944
 
945
static inline void
946
umka_sys_write_text(size_t x, size_t y, uint32_t color, int asciiz,
947
                    int fill_background, int font_and_encoding,
948
                    int draw_to_buffer, int scale_factor, const char *string,
949
                    size_t length, uintptr_t background_color_or_buffer) {
950
    __asm__ __inline__ __volatile__ (
951
        "call   i40"
952
        :
953
        : "a"(4),
954
          "b"((x << 16) + y),
955
          "c"((asciiz << 31) + (fill_background << 30)
956
              + (font_and_encoding << 28) + (draw_to_buffer << 27)
957
              + (scale_factor << 24) + color),
958
          "d"(string),
959
          "S"(length),
960
          "D"(background_color_or_buffer)
961
        : "memory");
962
}
963
 
964
static inline void
965
umka_sys_put_image(void *image, size_t xsize, size_t ysize, size_t x,
966
                   size_t y) {
967
    __asm__ __inline__ __volatile__ (
968
        "call   i40"
969
        :
970
        : "a"(7),
971
          "b"(image),
972
          "c"((xsize << 16) + ysize),
973
          "d"((x << 16) + y)
974
        : "memory");
975
}
976
 
977
static inline void
978
umka_sys_button(size_t x, size_t xsize, size_t y, size_t ysize,
979
                size_t button_id, int draw_button, int draw_frame,
980
                uint32_t color) {
981
    __asm__ __inline__ __volatile__ (
982
        "call   i40"
983
        :
984
        : "a"(8),
985
          "b"((x << 16) + xsize),
986
          "c"((y << 16) + ysize),
987
          "d"((!draw_button << 30) + (!draw_frame << 29) + button_id),
988
          "S"(color)
989
        : "memory");
990
}
991
 
992
static inline void
993
umka_sys_process_info(int32_t pid, void *param) {
994
    __asm__ __inline__ __volatile__ (
995
        "call   i40"
996
        :
997
        : "a"(9),
998
          "b"(param),
999
          "c"(pid)
1000
        : "memory");
1001
}
1002
 
1003
static inline void
1004
umka_sys_window_redraw(int begin_end) {
1005
    __asm__ __inline__ __volatile__ (
1006
        "call   i40"
1007
        :
1008
        : "a"(12),
1009
          "b"(begin_end)
1010
        : "memory");
1011
}
1012
 
1013
static inline void
1014
umka_sys_draw_rect(size_t x, size_t xsize, size_t y, size_t ysize,
1015
                   uint32_t color, int gradient) {
1016
    __asm__ __inline__ __volatile__ (
1017
        "call   i40"
1018
        :
1019
        : "a"(13),
1020
          "b"((x << 16) + xsize),
1021
          "c"((y << 16) + ysize),
1022
          "d"((gradient << 31) + color)
1023
        : "memory");
1024
}
1025
 
1026
static inline void
1027
umka_sys_get_screen_size(uint32_t *xsize, uint32_t *ysize) {
1028
    uint32_t xysize;
1029
    __asm__ __inline__ __volatile__ (
1030
        "call   i40"
1031
        : "=a"(xysize)
1032
        : "a"(14)
1033
        : "memory");
1034
    *xsize = (xysize >> 16) + 1;
1035
    *ysize = (xysize & 0xffffu) + 1;
1036
}
1037
 
1038
static inline void
1039
umka_sys_bg_set_size(uint32_t xsize, uint32_t ysize) {
1040
    __asm__ __inline__ __volatile__ (
1041
        "call   i40"
1042
        :
1043
        : "a"(15),
1044
          "b"(1),
1045
          "c"(xsize),
1046
          "d"(ysize)
1047
        : "memory");
1048
}
1049
 
1050
static inline void
1051
umka_sys_bg_put_pixel(uint32_t offset, uint32_t color) {
1052
    __asm__ __inline__ __volatile__ (
1053
        "call   i40"
1054
        :
1055
        : "a"(15),
1056
          "b"(2),
1057
          "c"(offset),
1058
          "d"(color)
1059
        : "memory");
1060
}
1061
 
1062
static inline void
1063
umka_sys_bg_redraw() {
1064
    __asm__ __inline__ __volatile__ (
1065
        "call   i40"
1066
        :
1067
        : "a"(15),
1068
          "b"(3)
1069
        : "memory");
1070
}
1071
 
1072
static inline void
1073
umka_sys_bg_set_mode(uint32_t mode) {
1074
    __asm__ __inline__ __volatile__ (
1075
        "call   i40"
1076
        :
1077
        : "a"(15),
1078
          "b"(4),
1079
          "c"(mode)
1080
        : "memory");
1081
}
1082
 
1083
static inline void
1084
umka_sys_bg_put_img(void *image, size_t offset, size_t size) {
1085
    __asm__ __inline__ __volatile__ (
1086
        "call   i40"
1087
        :
1088
        : "a"(15),
1089
          "b"(5),
1090
          "c"(image),
1091
          "d"(offset),
1092
          "S"(size)
1093
        : "memory");
1094
}
1095
 
1096
static inline void *
1097
umka_sys_bg_map() {
1098
    void *addr;
1099
    __asm__ __inline__ __volatile__ (
1100
        "call   i40"
1101
        : "=a"(addr)
1102
        : "a"(15),
1103
          "b"(6)
1104
        : "memory");
1105
    return addr;
1106
}
1107
 
1108
static inline uint32_t
1109
umka_sys_bg_unmap(void *addr) {
1110
    uint32_t status;
1111
    __asm__ __inline__ __volatile__ (
1112
        "call   i40"
1113
        : "=a"(status)
1114
        : "a"(15),
1115
          "b"(7),
1116
          "c"(addr)
1117
        : "memory");
1118
    return status;
1119
}
1120
 
1121
static inline void
1122
umka_sys_set_cwd(const char *dir) {
1123
    __asm__ __inline__ __volatile__ (
1124
        "call   i40"
1125
        :
1126
        : "a"(30),
1127
          "b"(1),
1128
          "c"(dir)
1129
        : "memory");
1130
}
1131
 
1132
static inline void
1133
umka_sys_get_cwd(const char *buf, size_t len) {
1134
    __asm__ __inline__ __volatile__ (
1135
        "call   i40"
1136
        :
1137
        : "a"(30),
1138
          "b"(2),
1139
          "c"(buf),
1140
          "d"(len)
1141
        : "memory");
1142
}
1143
 
1144
static inline void
1145
umka_sys_draw_line(size_t x, size_t xend, size_t y, size_t yend, uint32_t color,
1146
                   int invert) {
1147
    __asm__ __inline__ __volatile__ (
1148
        "call   i40"
1149
        :
1150
        : "a"(38),
1151
          "b"((x << 16) + xend),
1152
          "c"((y << 16) + yend),
1153
          "d"((invert << 24) + color)
1154
        : "memory");
1155
}
1156
 
1157
static inline void
1158
umka_sys_display_number(int is_pointer, int base, int digits_to_display,
1159
                        int is_qword, int show_leading_zeros,
1160
                        int number_or_pointer, size_t x, size_t y,
1161
                        uint32_t color, int fill_background, int font,
1162
                        int draw_to_buffer, int scale_factor,
1163
                        uintptr_t background_color_or_buffer) {
1164
    __asm__ __inline__ __volatile__ (
1165
        "call   i40"
1166
        :
1167
        : "a"(47),
1168
          "b"(is_pointer + (base << 8) + (digits_to_display << 16)
1169
              + (is_qword << 30) + (show_leading_zeros << 31)),
1170
          "c"(number_or_pointer),
1171
          "d"((x << 16) + y),
1172
          "S"(color + (fill_background << 30) + (font << 28)
1173
              + (draw_to_buffer << 27) + (scale_factor << 24)),
1174
          "D"(background_color_or_buffer)
1175
        : "memory");
1176
}
1177
 
1178
static inline void
1179
umka_sys_set_button_style(int style) {
1180
    __asm__ __inline__ __volatile__ (
1181
        "call   i40"
1182
        :
1183
        : "a"(48),
1184
          "b"(1),
1185
          "c"(style)
1186
        : "memory");
1187
}
1188
 
1189
static inline void
1190
umka_sys_set_window_colors(void *colors) {
1191
    __asm__ __inline__ __volatile__ (
1192
        "call   i40"
1193
        :
1194
        : "a"(48),
1195
          "b"(2),
1196
          "c"(colors),
1197
          "d"(40)
1198
        : "memory");
1199
}
1200
 
1201
static inline void
1202
umka_sys_get_window_colors(void *colors) {
1203
    __asm__ __inline__ __volatile__ (
1204
        "call   i40"
1205
        :
1206
        : "a"(48),
1207
          "b"(3),
1208
          "c"(colors),
1209
          "d"(40)
1210
        : "memory");
1211
}
1212
 
1213
static inline uint32_t
1214
umka_sys_get_skin_height() {
1215
    uint32_t skin_height;
1216
    __asm__ __inline__ __volatile__ (
1217
        "call   i40"
1218
        : "=a"(skin_height)
1219
        : "a"(48),
1220
          "b"(4)
1221
        : "memory");
1222
    return skin_height;
1223
}
1224
 
1225
static inline void
1226
umka_sys_get_screen_area(rect_t *wa) {
1227
    uint32_t eax, ebx;
1228
    __asm__ __inline__ __volatile__ (
1229
        "call   i40"
1230
        : "=a"(eax),
1231
          "=b"(ebx)
1232
        : "a"(48),
1233
          "b"(5)
1234
        : "memory");
1235
    wa->left   = eax >> 16;
1236
    wa->right  = eax & 0xffffu;
1237
    wa->top    = ebx >> 16;
1238
    wa->bottom = ebx & 0xffffu;
1239
}
1240
 
1241
static inline void
1242
umka_sys_set_screen_area(rect_t *wa) {
1243
    uint32_t ecx, edx;
1244
    ecx = (wa->left << 16) + wa->right;
1245
    edx = (wa->top << 16) + wa->bottom;
1246
    __asm__ __inline__ __volatile__ (
1247
        "call   i40"
1248
        :
1249
        : "a"(48),
1250
          "b"(6),
1251
          "c"(ecx),
1252
          "d"(edx)
1253
        : "memory");
1254
}
1255
 
1256
static inline void
1257
umka_sys_get_skin_margins(rect_t *wa) {
1258
    uint32_t eax, ebx;
1259
    __asm__ __inline__ __volatile__ (
1260
        "call   i40"
1261
        : "=a"(eax),
1262
          "=b"(ebx)
1263
        : "a"(48),
1264
          "b"(7)
1265
        : "memory");
1266
    wa->left   = eax >> 16;
1267
    wa->right  = eax & 0xffffu;
1268
    wa->top    = ebx >> 16;
1269
    wa->bottom = ebx & 0xffffu;
1270
}
1271
 
1272
static inline int32_t
1273
umka_sys_set_skin(const char *path) {
1274
    int32_t status;
1275
    __asm__ __inline__ __volatile__ (
1276
        "call   i40"
1277
        : "=a"(status)
1278
        : "a"(48),
1279
          "b"(8),
1280
          "c"(path)
1281
        : "memory");
1282
    return status;
1283
}
1284
 
1285
static inline int
1286
umka_sys_get_font_smoothing() {
1287
    int type;
1288
    __asm__ __inline__ __volatile__ (
1289
        "call   i40"
1290
        : "=a"(type)
1291
        : "a"(48),
1292
          "b"(9)
1293
        : "memory");
1294
    return type;
1295
}
1296
 
1297
static inline void
1298
umka_sys_set_font_smoothing(int type) {
1299
    __asm__ __inline__ __volatile__ (
1300
        "call   i40"
1301
        :
1302
        : "a"(48),
1303
          "b"(10),
1304
          "c"(type)
1305
        : "memory");
1306
}
1307
 
1308
static inline int
1309
umka_sys_get_font_size() {
1310
    uint32_t size;
1311
    __asm__ __inline__ __volatile__ (
1312
        "call   i40"
1313
        : "=a"(size)
1314
        : "a"(48),
1315
          "b"(11)
1316
        : "memory");
1317
    return size;
1318
}
1319
 
1320
static inline void
1321
umka_sys_set_font_size(uint32_t size) {
1322
    __asm__ __inline__ __volatile__ (
1323
        "call   i40"
1324
        :
1325
        : "a"(48),
1326
          "b"(12),
1327
          "c"(size)
1328
        : "memory");
1329
}
1330
 
9338 Boppan 1331
void
9325 Boppan 1332
umka_sys_put_image_palette(void *image, size_t xsize, size_t ysize,
1333
                           size_t x, size_t y, size_t bpp, void *palette,
9338 Boppan 1334
                           size_t row_offset);
9325 Boppan 1335
 
1336
static inline void
1337
umka_sys_move_window(size_t x, size_t y, ssize_t xsize, ssize_t ysize) {
1338
    __asm__ __inline__ __volatile__ (
1339
        "call   i40"
1340
        :
1341
        : "a"(67),
1342
          "b"(x),
1343
          "c"(y),
1344
          "d"(xsize),
1345
          "S"(ysize)
1346
        : "memory");
1347
}
1348
 
1349
static inline void
1350
umka_sys_lfn(void *f7080sXarg, f7080ret_t *r, f70or80_t f70or80) {
1351
    __asm__ __inline__ __volatile__ (
1352
        "call   i40"
1353
        : "=a"(r->status),
1354
          "=b" (r->count)
1355
        : "a"(f70or80),
1356
          "b"(f7080sXarg)
1357
        : "memory");
1358
}
1359
 
1360
static inline void
1361
umka_sys_set_window_caption(const char *caption, int encoding) {
1362
    __asm__ __inline__ __volatile__ (
1363
        "call   i40"
1364
        :
1365
        : "a"(71),
1366
          "b"(encoding ? 2 : 1),
1367
          "c"(caption),
1368
          "d"(encoding)
1369
        : "memory");
1370
}
1371
 
1372
static inline void
1373
umka_sys_blit_bitmap(int operation, int background, int transparent,
1374
                     int client_relative, void *params) {
1375
    __asm__ __inline__ __volatile__ (
1376
        "call   i40"
1377
        :
1378
        : "a"(73),
1379
          "b"((client_relative << 29) + (transparent << 5) + (background << 4)
1380
              + operation),
1381
          "c"(params)
1382
        : "memory");
1383
}
1384
 
1385
static inline uint32_t
1386
umka_sys_net_get_dev_count() {
1387
    uint32_t count;
1388
    __asm__ __inline__ __volatile__ (
1389
        "call   i40"
1390
        : "=a"(count)
1391
        : "a"(74),
1392
          "b"(255)
1393
        : "memory");
1394
    return count;
1395
}
1396
 
1397
static inline int32_t
1398
umka_sys_net_get_dev_type(uint8_t dev_num) {
1399
    int32_t type;
1400
    __asm__ __inline__ __volatile__ (
1401
        "call   i40"
1402
        : "=a"(type)
1403
        : "a"(74),
1404
          "b"((dev_num << 8) + 0)
1405
        : "memory");
1406
    return type;
1407
}
1408
 
1409
static inline int32_t
1410
umka_sys_net_get_dev_name(uint8_t dev_num, char *name) {
1411
    int32_t status;
1412
    __asm__ __inline__ __volatile__ (
1413
        "call   i40"
1414
        : "=a"(status)
1415
        : "a"(74),
1416
          "b"((dev_num << 8) + 1),
1417
          "c"(name)
1418
        : "memory");
1419
    return status;
1420
}
1421
 
1422
static inline int32_t
1423
umka_sys_net_dev_reset(uint8_t dev_num) {
1424
    int32_t status;
1425
    __asm__ __inline__ __volatile__ (
1426
        "call   i40"
1427
        : "=a"(status)
1428
        : "a"(74),
1429
          "b"((dev_num << 8) + 2)
1430
        : "memory");
1431
    return status;
1432
}
1433
 
1434
static inline int32_t
1435
umka_sys_net_dev_stop(uint8_t dev_num) {
1436
    int32_t status;
1437
    __asm__ __inline__ __volatile__ (
1438
        "call   i40"
1439
        : "=a"(status)
1440
        : "a"(74),
1441
          "b"((dev_num << 8) + 3)
1442
        : "memory");
1443
    return status;
1444
}
1445
 
1446
static inline intptr_t
1447
umka_sys_net_get_dev(uint8_t dev_num) {
1448
    intptr_t dev;
1449
    __asm__ __inline__ __volatile__ (
1450
        "call   i40"
1451
        : "=a"(dev)
1452
        : "a"(74),
1453
          "b"((dev_num << 8) + 4)
1454
        : "memory");
1455
    return dev;
1456
}
1457
 
1458
static inline uint32_t
1459
umka_sys_net_get_packet_tx_count(uint8_t dev_num) {
1460
    uint32_t count;
1461
    __asm__ __inline__ __volatile__ (
1462
        "call   i40"
1463
        : "=a"(count)
1464
        : "a"(74),
1465
          "b"((dev_num << 8) + 6)
1466
        : "memory");
1467
    return count;
1468
}
1469
 
1470
static inline uint32_t
1471
umka_sys_net_get_packet_rx_count(uint8_t dev_num) {
1472
    uint32_t count;
1473
    __asm__ __inline__ __volatile__ (
1474
        "call   i40"
1475
        : "=a"(count)
1476
        : "a"(74),
1477
          "b"((dev_num << 8) + 7)
1478
        : "memory");
1479
    return count;
1480
}
1481
 
1482
static inline uint32_t
1483
umka_sys_net_get_byte_tx_count(uint8_t dev_num) {
1484
    uint32_t count;
1485
    __asm__ __inline__ __volatile__ (
1486
        "call   i40"
1487
        : "=a"(count)
1488
        : "a"(74),
1489
          "b"((dev_num << 8) + 8)
1490
        : "memory");
1491
    return count;
1492
}
1493
 
1494
static inline uint32_t
1495
umka_sys_net_get_byte_rx_count(uint8_t dev_num) {
1496
    uint32_t count;
1497
    __asm__ __inline__ __volatile__ (
1498
        "call   i40"
1499
        : "=a"(count)
1500
        : "a"(74),
1501
          "b"((dev_num << 8) + 9)
1502
        : "memory");
1503
    return count;
1504
}
1505
 
1506
static inline uint32_t
1507
umka_sys_net_get_link_status(uint8_t dev_num) {
1508
    uint32_t status;
1509
    __asm__ __inline__ __volatile__ (
1510
        "call   i40"
1511
        : "=a"(status)
1512
        : "a"(74),
1513
          "b"((dev_num << 8) + 10)
1514
        : "memory");
1515
    return status;
1516
}
1517
 
1518
static inline f75ret_t
1519
umka_sys_net_open_socket(uint32_t domain, uint32_t type, uint32_t protocol) {
1520
    f75ret_t r;
1521
    __asm__ __inline__ __volatile__ (
1522
        "call   i40"
1523
        : "=a"(r.value),
1524
          "=b"(r.errorcode)
1525
        : "a"(75),
1526
          "b"(0),
1527
          "c"(domain),
1528
          "d"(type),
1529
          "S"(protocol)
1530
        : "memory");
1531
    return r;
1532
}
1533
 
1534
static inline f75ret_t
1535
umka_sys_net_close_socket(uint32_t fd) {
1536
    f75ret_t r;
1537
    __asm__ __inline__ __volatile__ (
1538
        "call   i40"
1539
        : "=a"(r.value),
1540
          "=b"(r.errorcode)
1541
        : "a"(75),
1542
          "b"(1),
1543
          "c"(fd)
1544
        : "memory");
1545
    return r;
1546
}
1547
 
1548
static inline f75ret_t
1549
umka_sys_net_bind(uint32_t fd, void *sockaddr, size_t sockaddr_len) {
1550
    f75ret_t r;
1551
    __asm__ __inline__ __volatile__ (
1552
        "call   i40"
1553
        : "=a"(r.value),
1554
          "=b"(r.errorcode)
1555
        : "a"(75),
1556
          "b"(2),
1557
          "c"(fd),
1558
          "d"(sockaddr),
1559
          "S"(sockaddr_len)
1560
        : "memory");
1561
    return r;
1562
}
1563
 
1564
static inline f75ret_t
1565
umka_sys_net_listen(uint32_t fd, uint32_t backlog) {
1566
    f75ret_t r;
1567
    __asm__ __inline__ __volatile__ (
1568
        "call   i40"
1569
        : "=a"(r.value),
1570
          "=b"(r.errorcode)
1571
        : "a"(75),
1572
          "b"(3),
1573
          "c"(fd),
1574
          "d"(backlog)
1575
        : "memory");
1576
    return r;
1577
}
1578
 
1579
static inline f75ret_t
1580
umka_sys_net_connect(uint32_t fd, void *sockaddr, size_t sockaddr_len) {
1581
    f75ret_t r;
1582
    __asm__ __inline__ __volatile__ (
1583
        "call   i40"
1584
        : "=a"(r.value),
1585
          "=b"(r.errorcode)
1586
        : "a"(75),
1587
          "b"(4),
1588
          "c"(fd),
1589
          "d"(sockaddr),
1590
          "S"(sockaddr_len)
1591
        : "memory");
1592
    return r;
1593
}
1594
 
1595
static inline f75ret_t
1596
umka_sys_net_accept(uint32_t fd, void *sockaddr, size_t sockaddr_len) {
1597
    f75ret_t r;
1598
    __asm__ __inline__ __volatile__ (
1599
        "call   i40"
1600
        : "=a"(r.value),
1601
          "=b"(r.errorcode)
1602
        : "a"(75),
1603
          "b"(5),
1604
          "c"(fd),
1605
          "d"(sockaddr),
1606
          "S"(sockaddr_len)
1607
        : "memory");
1608
    return r;
1609
}
1610
 
1611
static inline f75ret_t
1612
umka_sys_net_send(uint32_t fd, void *buf, size_t buf_len, uint32_t flags) {
1613
    f75ret_t r;
1614
    __asm__ __inline__ __volatile__ (
1615
        "call   i40"
1616
        : "=a"(r.value),
1617
          "=b"(r.errorcode)
1618
        : "a"(75),
1619
          "b"(6),
1620
          "c"(fd),
1621
          "d"(buf),
1622
          "S"(buf_len),
1623
          "D"(flags)
1624
        : "memory");
1625
    return r;
1626
}
1627
 
1628
static inline f75ret_t
1629
umka_sys_net_receive(uint32_t fd, void *buf, size_t buf_len, uint32_t flags) {
1630
    f75ret_t r;
1631
    __asm__ __inline__ __volatile__ (
1632
        "call   i40"
1633
        : "=a"(r.value),
1634
          "=b"(r.errorcode)
1635
        : "a"(75),
1636
          "b"(7),
1637
          "c"(fd),
1638
          "d"(buf),
1639
          "S"(buf_len),
1640
          "D"(flags)
1641
        : "memory");
1642
    return r;
1643
}
1644
 
1645
static inline f76ret_t
1646
umka_sys_net_eth_read_mac(uint32_t dev_num) {
1647
    f76ret_t r;
1648
    __asm__ __inline__ __volatile__ (
1649
        "call   i40"
1650
        : "=a"(r.eax),
1651
          "=b"(r.ebx)
1652
        : "a"(76),
1653
          "b"((0 << 16) + (dev_num << 8) + 0)
1654
        : "memory");
1655
    return r;
1656
}
1657
 
1658
// Function 76, Protocol 1 - IPv4, Subfunction 0, Read # Packets sent =
1659
// Function 76, Protocol 1 - IPv4, Subfunction 1, Read # Packets rcvd =
1660
 
1661
static inline f76ret_t
1662
umka_sys_net_ipv4_get_addr(uint32_t dev_num) {
1663
    f76ret_t r;
1664
    __asm__ __inline__ __volatile__ (
1665
        "call   i40"
1666
        : "=a"(r.eax),
1667
          "=b"(r.ebx)
1668
        : "a"(76),
1669
          "b"((1 << 16) + (dev_num << 8) + 2)
1670
        : "memory");
1671
    return r;
1672
}
1673
 
1674
static inline f76ret_t
1675
umka_sys_net_ipv4_set_addr(uint32_t dev_num, uint32_t addr) {
1676
    f76ret_t r;
1677
    __asm__ __inline__ __volatile__ (
1678
        "call   i40"
1679
        : "=a"(r.eax),
1680
          "=b"(r.ebx)
1681
        : "a"(76),
1682
          "b"((1 << 16) + (dev_num << 8) + 3),
1683
          "c"(addr)
1684
        : "memory");
1685
    return r;
1686
}
1687
 
1688
static inline f76ret_t
1689
umka_sys_net_ipv4_get_dns(uint32_t dev_num) {
1690
    f76ret_t r;
1691
    __asm__ __inline__ __volatile__ (
1692
        "call   i40"
1693
        : "=a"(r.eax),
1694
          "=b"(r.ebx)
1695
        : "a"(76),
1696
          "b"((1 << 16) + (dev_num << 8) + 4)
1697
        : "memory");
1698
    return r;
1699
}
1700
 
1701
static inline f76ret_t
1702
umka_sys_net_ipv4_set_dns(uint32_t dev_num, uint32_t dns) {
1703
    f76ret_t r;
1704
    __asm__ __inline__ __volatile__ (
1705
        "call   i40"
1706
        : "=a"(r.eax),
1707
          "=b"(r.ebx)
1708
        : "a"(76),
1709
          "b"((1 << 16) + (dev_num << 8) + 5),
1710
          "c"(dns)
1711
        : "memory");
1712
    return r;
1713
}
1714
 
1715
static inline f76ret_t
1716
umka_sys_net_ipv4_get_subnet(uint32_t dev_num) {
1717
    f76ret_t r;
1718
    __asm__ __inline__ __volatile__ (
1719
        "call   i40"
1720
        : "=a"(r.eax),
1721
          "=b"(r.ebx)
1722
        : "a"(76),
1723
          "b"((1 << 16) + (dev_num << 8) + 6)
1724
        : "memory");
1725
    return r;
1726
}
1727
 
1728
static inline f76ret_t
1729
umka_sys_net_ipv4_set_subnet(uint32_t dev_num, uint32_t subnet) {
1730
    f76ret_t r;
1731
    __asm__ __inline__ __volatile__ (
1732
        "call   i40"
1733
        : "=a"(r.eax),
1734
          "=b"(r.ebx)
1735
        : "a"(76),
1736
          "b"((1 << 16) + (dev_num << 8) + 7),
1737
          "c"(subnet)
1738
        : "memory");
1739
    return r;
1740
}
1741
 
1742
static inline f76ret_t
1743
umka_sys_net_ipv4_get_gw(uint32_t dev_num) {
1744
    f76ret_t r;
1745
    __asm__ __inline__ __volatile__ (
1746
        "call   i40"
1747
        : "=a"(r.eax),
1748
          "=b"(r.ebx)
1749
        : "a"(76),
1750
          "b"((1 << 16) + (dev_num << 8) + 8)
1751
        : "memory");
1752
    return r;
1753
}
1754
 
1755
static inline f76ret_t
1756
umka_sys_net_ipv4_set_gw(uint32_t dev_num, uint32_t gw) {
1757
    f76ret_t r;
1758
    __asm__ __inline__ __volatile__ (
1759
        "call   i40"
1760
        : "=a"(r.eax),
1761
          "=b"(r.ebx)
1762
        : "a"(76),
1763
          "b"((1 << 16) + (dev_num << 8) + 9),
1764
          "c"(gw)
1765
        : "memory");
1766
    return r;
1767
}
1768
 
1769
// Function 76, Protocol 2 - ICMP, Subfunction 0, Read # Packets sent =
1770
// Function 76, Protocol 2 - ICMP, Subfunction 1, Read # Packets rcvd =
1771
// Function 76, Protocol 3 - UDP, Subfunction 0, Read # Packets sent ==
1772
// Function 76, Protocol 3 - UDP, Subfunction 1, Read # Packets rcvd ==
1773
// Function 76, Protocol 4 - TCP, Subfunction 0, Read # Packets sent ==
1774
// Function 76, Protocol 4 - TCP, Subfunction 1, Read # Packets rcvd ==
1775
// Function 76, Protocol 5 - ARP, Subfunction 0, Read # Packets sent ==
1776
// Function 76, Protocol 5 - ARP, Subfunction 1, Read # Packets rcvd ==
1777
static inline f76ret_t
1778
umka_sys_net_arp_get_count(uint32_t dev_num) {
1779
    f76ret_t r;
1780
    __asm__ __inline__ __volatile__ (
1781
        "call   i40"
1782
        : "=a"(r.eax),
1783
          "=b"(r.ebx)
1784
        : "a"(76),
1785
          "b"((5 << 16) + (dev_num << 8) + 2)
1786
        : "memory");
1787
    return r;
1788
}
1789
 
1790
static inline f76ret_t
1791
umka_sys_net_arp_get_entry(uint32_t dev_num, uint32_t arp_num, void *buf) {
1792
    f76ret_t r;
1793
    __asm__ __inline__ __volatile__ (
1794
        "call   i40"
1795
        : "=a"(r.eax),
1796
          "=b"(r.ebx)
1797
        : "a"(76),
1798
          "b"((5 << 16) + (dev_num << 8) + 3),
1799
          "c"(arp_num),
1800
          "D"(buf)
1801
        : "memory");
1802
    return r;
1803
}
1804
 
1805
static inline f76ret_t
1806
umka_sys_net_arp_add_entry(uint32_t dev_num, void *buf) {
1807
    f76ret_t r;
1808
    __asm__ __inline__ __volatile__ (
1809
        "call   i40"
1810
        : "=a"(r.eax),
1811
          "=b"(r.ebx)
1812
        : "a"(76),
1813
          "b"((5 << 16) + (dev_num << 8) + 4),
1814
          "S"(buf)
1815
        : "memory");
1816
    return r;
1817
}
1818
 
1819
static inline f76ret_t
1820
umka_sys_net_arp_del_entry(uint32_t dev_num, int32_t arp_num) {
1821
    f76ret_t r;
1822
    __asm__ __inline__ __volatile__ (
1823
        "call   i40"
1824
        : "=a"(r.eax),
1825
          "=b"(r.ebx)
1826
        : "a"(76),
1827
          "b"((5 << 16) + (dev_num << 8) + 5),
1828
          "c"(arp_num)
1829
        : "memory");
1830
    return r;
1831
}
1832
 
1833
// Function 76, Protocol 5 - ARP, Subfunction 6, Send ARP announce ==
1834
// Function 76, Protocol 5 - ARP, Subfunction 7, Read # conflicts ===
1835
 
1836
#endif  // UMKA_H_INCLUDED