├── .gitignore ├── src ├── entry │ ├── start.s │ └── boot.c ├── lib │ └── common.c └── ofw │ ├── time.c │ ├── common.c │ ├── mem.c │ ├── control.c │ ├── interface.c │ ├── io.c │ └── tree.c ├── kpartx └── kpartx.sh ├── README.md ├── linker.ld ├── loader ├── def.fth └── load.fth ├── include └── ofw.h ├── COPYING └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | *.elf 2 | *.bin 3 | *.APM 4 | bootinfo.txt 5 | *.json 6 | .cache 7 | *.idx 8 | -------------------------------------------------------------------------------- /src/entry/start.s: -------------------------------------------------------------------------------- 1 | .globl _start 2 | .extern ofw 3 | _start: 4 | lis 9, ofw@ha 5 | ori 9, 9, ofw@l 6 | stw 5, 0(9) 7 | b main 8 | -------------------------------------------------------------------------------- /kpartx/kpartx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | LOOP=$(sudo kpartx -s -a -v DISK.APM | awk -F'[ ]' '{print $3}' | tail -n1 ) 3 | sudo mkfs.hfsplus /dev/mapper/$LOOP 4 | sudo mount -o loop /dev/mapper/$LOOP /mnt/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # powerpc-ofw-boot 2 | Boots through OpenFirmware. 3 | Produces a HFS+ disk image formatted with Apple Partition Map partition scheme, compatible with PowerPC-based Macs. 4 | 5 | Run it with QEMU : 6 | 7 | ```make && make run``` 8 | -------------------------------------------------------------------------------- /src/lib/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void puts(char* str, int len) 4 | { 5 | char cmd[len+8]; 6 | cmd[0] = '.'; cmd[1] = '"'; 7 | cmd[2] = ' '; 8 | for (int i = 3; i < len+3; i++) 9 | { 10 | cmd[i] = str[i-3]; 11 | } 12 | cmd[len+3] = '"'; cmd[len+4] = ' '; 13 | cmd[len+5] = 'c'; cmd[len+6] = 'r'; 14 | cmd[len+7] = 0; 15 | ofw_interpret(cmd, 0, 0, 0, 0); 16 | } 17 | -------------------------------------------------------------------------------- /linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0x02000000; 6 | .text BLOCK(4K) : ALIGN(4K) 7 | { 8 | *(.text) 9 | } 10 | . = 0x02100000; 11 | .data BLOCK(4K) : ALIGN(4K) 12 | { 13 | 14 | *(.rodata) 15 | *(.data) 16 | } 17 | .bss BLOCK(4K) (NOLOAD) : ALIGN(4K) 18 | { 19 | *(.bss) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /loader/def.fth: -------------------------------------------------------------------------------- 1 | : initmsg ." powerpc-ofw-boot" cr ; 2 | : fba frame-buffer-adr ; 3 | : beige-fba 80000000 ; : mac99-fba 81000000 ; 4 | : hardware-error ." Hardware not supported." cr ; 5 | : beige-message ." Beige hardware detected" cr ; 6 | : mac99-message ." mac99 hardware detected" cr ; 7 | : beige-magic-number 0BE ; 8 | : mac99-magic-number 05A ; 9 | : magic-number-offset 0 ; 10 | : width-offset 4 ; 11 | : height-offset 8 ; 12 | -------------------------------------------------------------------------------- /src/ofw/time.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void (*ofw)(); 4 | 5 | int32_t ofw_milliseconds(void) 6 | { 7 | struct 8 | { 9 | char* service; 10 | int32_t n_args; 11 | int32_t n_rets; 12 | int32_t ret; 13 | } ofw_arg; 14 | 15 | SERVICE("milliseconds", 13, 0, 1); 16 | 17 | ofw(&ofw_arg); 18 | 19 | return ofw_arg.ret; 20 | } 21 | -------------------------------------------------------------------------------- /src/ofw/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void (*ofw)(); 4 | 5 | int32_t ofw_test(char* name) 6 | { 7 | struct 8 | { 9 | char* service; 10 | int32_t n_args; 11 | int32_t n_rets; 12 | char* arg; 13 | int32_t ret; 14 | } ofw_arg; 15 | 16 | SERVICE("test", 5, 1, 1); 17 | 18 | ofw_arg.arg = name; 19 | 20 | ofw(&ofw_arg); 21 | return ofw_arg.ret; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /loader/load.fth: -------------------------------------------------------------------------------- 1 | true to use-console? 2 | false to ignore-output? 3 | stdout @ 0= if 4 | " screen" output 5 | install-console 6 | then 7 | ." hello!! :D" cr 8 | 9 | : loader-location " :2,\boot\kernel.elf" ; 10 | 11 | " dir " encode-bytes " &device;" encode-bytes 12 | encode+ 13 | " :2,\" encode-bytes encode+ 14 | evaluate 15 | 16 | " load &device;" encode-bytes 17 | loader-location encode-bytes 18 | encode+ 19 | evaluate 20 | go 21 | 22 | variable run 23 | 0 run ! 24 | run @ 0 = if 1 0 do 0 +loop then 25 | -------------------------------------------------------------------------------- /src/entry/boot.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void (*ofw)(); 4 | void __eabi(); 5 | 6 | void __stack_chk_fail_local(void) 7 | { 8 | } 9 | void __eabi(void) 10 | { 11 | } 12 | 13 | //void* ofw_interpret(char* cmd, int32_t* stack_args, int n_stack_args, int n_ret_args, int32_t* reta 14 | void main(void) 15 | { 16 | ofw_interpret("show-devs", 0, 0, 0, 0); 17 | puts("Press any key to continue", 25); 18 | ofw_interpret("blink-screen", 0, 0, 0, 0); 19 | ofw_interpret("key", 0, 0, 1, (int32_t*)0x03020000); 20 | 21 | puts("Starting...", 11); 22 | if (ofw_test("open")) 23 | { 24 | asm("mr 27, 28"); 25 | asm("b $"); 26 | } 27 | else 28 | { 29 | asm("mr 30, 31"); 30 | asm("b $"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /include/ofw.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SERVICE(name, len, args, rets) \ 4 | char _service[len] = name; \ 5 | ofw_arg.service = _service; \ 6 | ofw_arg.n_args = args; \ 7 | ofw_arg.n_rets = rets; 8 | 9 | typedef int32_t phandle; 10 | typedef int32_t ihandle; 11 | 12 | void puts(char* str, int len); 13 | 14 | void* ofw_interpret(char* cmd, int32_t* stack_args, int n_stack_args, int n_ret_args, int32_t* retaddr); 15 | int32_t ofw_test(char* name); 16 | 17 | ihandle ofw_open(char* device_specifier); 18 | void ofw_close(ihandle instance); 19 | int32_t ofw_read(ihandle instance, void* addr, int32_t len); 20 | int32_t ofw_write(ihandle instance, void* addr, int32_t len); 21 | int32_t ofw_seek(ihandle instance, int32_t pos_hi, int32_t pos_lo); 22 | 23 | void* ofw_set_callback(void* addr); 24 | void ofw_set_symbol_lookup(void* sym_to_value, void* value_to_sym); 25 | -------------------------------------------------------------------------------- /src/ofw/mem.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void (*ofw)(); 4 | 5 | void* ofw_claim(void* virt, int32_t size, int32_t align) 6 | { 7 | struct 8 | { 9 | char* service; 10 | int32_t n_args; 11 | int32_t n_rets; 12 | void* arg1; 13 | int32_t arg2; 14 | int32_t arg3; 15 | void* ret; 16 | } ofw_arg; 17 | 18 | SERVICE("claim", 6, 3, 1); 19 | 20 | ofw_arg.arg1 = virt; 21 | ofw_arg.arg2 = size; 22 | ofw_arg.arg3 = align; 23 | 24 | ofw(&ofw_arg); 25 | return ofw_arg.ret; 26 | } 27 | 28 | 29 | void ofw_release(void* virt, int32_t size) 30 | { 31 | struct 32 | { 33 | char* service; 34 | int32_t n_args; 35 | int32_t n_rets; 36 | void* arg1; 37 | int32_t arg2; 38 | } ofw_arg; 39 | 40 | SERVICE("release", 8, 2, 0); 41 | 42 | ofw_arg.arg1 = virt; 43 | ofw_arg.arg2 = size; 44 | 45 | ofw(&ofw_arg); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2024, aramya 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /src/ofw/control.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void (*ofw)(); 4 | 5 | void ofw_boot(char* bootspec) 6 | { 7 | struct 8 | { 9 | char* service; 10 | int32_t n_args; 11 | int32_t n_rets; 12 | char* arg; 13 | } ofw_arg; 14 | 15 | SERVICE("boot", 5, 1, 0); 16 | 17 | ofw_arg.arg = bootspec; 18 | 19 | ofw(&ofw_arg); 20 | } 21 | 22 | void ofw_enter(void) 23 | { 24 | struct 25 | { 26 | char* service; 27 | int32_t n_args; 28 | int32_t n_rets; 29 | } ofw_arg; 30 | 31 | SERVICE("enter", 6, 0, 0); 32 | 33 | ofw(&ofw_arg); 34 | } 35 | 36 | void ofw_exit(void) 37 | { 38 | struct 39 | { 40 | char* service; 41 | int32_t n_args; 42 | int32_t n_rets; 43 | } ofw_arg; 44 | 45 | SERVICE("exit", 5, 0, 0); 46 | 47 | ofw(&ofw_arg); 48 | } 49 | 50 | void ofw_chain(void* virt, int32_t size, void* entry, void* args, int32_t len) 51 | { 52 | struct 53 | { 54 | char* service; 55 | int32_t n_args; 56 | int32_t n_rets; 57 | void* arg1; 58 | int32_t arg2; 59 | void* arg3; 60 | void* arg4; 61 | int32_t arg5; 62 | } ofw_arg; 63 | 64 | SERVICE("chain", 6, 5, 0); 65 | 66 | ofw_arg.arg1 = virt; 67 | ofw_arg.arg2 = size; 68 | ofw_arg.arg3 = entry; 69 | ofw_arg.arg4 = args; 70 | ofw_arg.arg5 = len; 71 | 72 | ofw(&ofw_arg); 73 | } 74 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MACHINE = mac99 2 | PPC = powerpc-eabi 3 | QEMU = qemu-system-ppc 4 | RES = 1600x900x32 5 | CPU = g4 6 | SOURCES_C = $(shell find src -name "*.c") 7 | SOURCES_S = $(shell find src -name "*.s") 8 | 9 | OBJECTS = $(SOURCES_C:.c=.elf) $(SOURCES_S:.s=.elf) 10 | 11 | .PHONY: clean run debug beige 12 | 13 | DISK.APM: kernel.elf bootinfo.txt kpartx/kpartx.sh 14 | dd bs=512K count=2 if=/dev/zero of=DISK.APM 15 | parted DISK.APM --script mklabel mac mkpart primary hfs+ 32.8KB 100% 16 | sudo chmod +x kpartx/kpartx.sh 17 | sudo ./kpartx/kpartx.sh 18 | sudo mkdir -p /mnt/ppc /mnt/boot 19 | sudo cp bootinfo.txt /mnt/ppc 20 | sudo cp kernel.elf /mnt/boot 21 | sudo umount /mnt/ 22 | sudo kpartx -d DISK.APM 23 | 24 | bootinfo.txt: loader/def.fth loader/load.fth 25 | @echo "MacRisc MacRisc3 MacRisc4" > $@ 26 | @sed 's/>/\>/g; s/> $@ 27 | @echo "" >> $@ 28 | @printf "\4" >> $@ 29 | 30 | kernel.elf: linker.ld $(OBJECTS) 31 | $(PPC)-ld -T $^ -o $@ 32 | 33 | %.elf: %.c 34 | $(PPC)-gcc -I include -c $< -o $@ 35 | 36 | %.elf: %.s 37 | $(PPC)-as -c $< -o $@ 38 | 39 | clean: 40 | rm -f *.APM *.txt *.elf 41 | find src -name "*.elf" -type f -delete 42 | 43 | run: 44 | $(QEMU) -hda *.APM -g $(RES) -machine $(MACHINE) -cpu $(CPU) 45 | 46 | debug: 47 | $(QEMU) -hda *.APM -d in_asm -g $(RES) -machine $(MACHINE) -cpu $(CPU) 48 | gdb: 49 | $(QEMU) -hda *.APM -s -S -g $(RES) -machine $(MACHINE) -cpu $(CPU) 50 | -------------------------------------------------------------------------------- /src/ofw/interface.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void (*ofw)(); 4 | 5 | void* ofw_interpret(char* cmd, int32_t* stack_args, int n_stack_args, int n_ret_args, int32_t* retaddr) 6 | { 7 | struct 8 | { 9 | char* service; 10 | int32_t n_args; 11 | int32_t n_rets; 12 | char* arg1; 13 | int32_t argN[n_stack_args]; 14 | int32_t ret1; 15 | int32_t retN[n_ret_args]; 16 | } ofw_arg; 17 | 18 | SERVICE("interpret", 10, 1+n_stack_args, n_ret_args); 19 | 20 | ofw_arg.arg1 = cmd; 21 | 22 | int i; 23 | for (i = 0; i < n_stack_args; i++) 24 | { 25 | ofw_arg.argN[i] = stack_args[i]; 26 | } 27 | 28 | ofw(&ofw_arg); 29 | 30 | *retaddr = ofw_arg.ret1; 31 | for (i = 1; i < n_ret_args+1; i++) 32 | { 33 | retaddr[i] = ofw_arg.retN[i]; 34 | } 35 | 36 | return retaddr; 37 | } 38 | 39 | void* ofw_set_callback(void* addr) 40 | { 41 | struct 42 | { 43 | char* service; 44 | int32_t n_args; 45 | int32_t n_rets; 46 | void* arg; 47 | void* ret; 48 | } ofw_arg; 49 | 50 | SERVICE("set-callback", 13, 1, 1); 51 | 52 | ofw_arg.arg = addr; 53 | 54 | ofw(&ofw_arg); 55 | return ofw_arg.ret; 56 | } 57 | 58 | void ofw_set_symbol_lookup(void* sym_to_value, void* value_to_sym) 59 | { 60 | struct 61 | { 62 | char* service; 63 | int32_t n_args; 64 | int32_t n_rets; 65 | void* arg1; 66 | void* arg2; 67 | } ofw_arg; 68 | 69 | SERVICE("set-symbol-lookup", 17, 2, 0); 70 | 71 | ofw_arg.arg1 = sym_to_value; 72 | ofw_arg.arg2 = value_to_sym; 73 | 74 | ofw(&ofw_arg); 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/ofw/io.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void (*ofw)(); 4 | 5 | ihandle ofw_open(char* device_specifier) 6 | { 7 | struct 8 | { 9 | char* service; 10 | int32_t n_args; 11 | int32_t n_rets; 12 | char* arg; 13 | ihandle ret; 14 | } ofw_arg; 15 | 16 | SERVICE("open", 5, 1, 1); 17 | 18 | ofw_arg.arg = device_specifier; 19 | 20 | ofw(&ofw_arg); 21 | return ofw_arg.ret; 22 | } 23 | 24 | void ofw_close(ihandle instance) 25 | { 26 | struct 27 | { 28 | char* service; 29 | int32_t n_args; 30 | int32_t n_rets; 31 | ihandle arg; 32 | } ofw_arg; 33 | 34 | SERVICE("close", 6, 1, 0); 35 | 36 | ofw_arg.arg = instance; 37 | 38 | ofw(&ofw_arg); 39 | } 40 | 41 | int32_t ofw_read(ihandle instance, void* addr, int32_t len) 42 | { 43 | struct 44 | { 45 | char* service; 46 | int32_t n_args; 47 | int32_t n_rets; 48 | ihandle arg1; 49 | void* arg2; 50 | int32_t arg3; 51 | int32_t ret; 52 | } ofw_arg; 53 | 54 | SERVICE("read", 5, 3, 1); 55 | 56 | ofw_arg.arg1 = instance; 57 | ofw_arg.arg2 = addr; 58 | ofw_arg.arg3 = len; 59 | 60 | ofw(&ofw_arg); 61 | 62 | return ofw_arg.ret; 63 | } 64 | 65 | int32_t ofw_write(ihandle instance, void* addr, int32_t len) 66 | { 67 | struct 68 | { 69 | char* service; 70 | int32_t n_args; 71 | int32_t n_rets; 72 | ihandle arg1; 73 | void* arg2; 74 | int32_t arg3; 75 | int32_t ret; 76 | } ofw_arg; 77 | 78 | SERVICE("write", 6, 3, 1); 79 | 80 | ofw_arg.arg1 = instance; 81 | ofw_arg.arg2 = addr; 82 | ofw_arg.arg3 = len; 83 | 84 | ofw(&ofw_arg); 85 | 86 | return ofw_arg.ret; 87 | 88 | } 89 | 90 | int32_t ofw_seek(ihandle instance, int32_t pos_hi, int32_t pos_lo) 91 | { 92 | struct 93 | { 94 | char* service; 95 | int32_t n_args; 96 | int32_t n_rets; 97 | ihandle arg1; 98 | int32_t* arg2; 99 | int32_t arg3; 100 | int32_t ret; 101 | } ofw_arg; 102 | 103 | SERVICE("seek", 5, 3, 1); 104 | 105 | ofw_arg.arg1 = instance; 106 | ofw_arg.arg2 = (int32_t*)pos_hi; 107 | ofw_arg.arg3 = pos_lo; 108 | 109 | ofw(&ofw_arg); 110 | 111 | return ofw_arg.ret; 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/ofw/tree.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void (*ofw)(); 4 | 5 | phandle ofw_child(phandle _child) 6 | { 7 | struct 8 | { 9 | char* service; 10 | int32_t n_args; 11 | int32_t n_rets; 12 | phandle arg; 13 | phandle ret; 14 | } ofw_arg; 15 | 16 | SERVICE("child", 6, 1, 1); 17 | 18 | ofw_arg.arg = _child; 19 | 20 | ofw(&ofw_arg); 21 | return ofw_arg.ret; 22 | } 23 | 24 | phandle ofw_parent(phandle _parent) 25 | { 26 | struct 27 | { 28 | char* service; 29 | int32_t n_args; 30 | int32_t n_rets; 31 | phandle arg; 32 | phandle ret; 33 | } ofw_arg; 34 | 35 | SERVICE("parent", 7, 1, 1); 36 | 37 | ofw_arg.arg = _parent; 38 | 39 | ofw(&ofw_arg); 40 | return ofw_arg.ret; 41 | } 42 | 43 | phandle ofw_instance_to_package(ihandle instance) 44 | { 45 | struct 46 | { 47 | char* service; 48 | int32_t n_args; 49 | int32_t n_rets; 50 | ihandle arg; 51 | phandle ret; 52 | } ofw_arg; 53 | 54 | SERVICE("instance-to-package", 20, 1, 1); 55 | 56 | ofw_arg.arg = instance; 57 | 58 | ofw(&ofw_arg); 59 | return ofw_arg.ret; 60 | } 61 | 62 | int32_t ofw_getproplen(phandle node, char* name) 63 | { 64 | struct 65 | { 66 | char* service; 67 | int32_t n_args; 68 | int32_t n_rets; 69 | phandle arg1; 70 | char* arg2; 71 | int32_t ret; 72 | } ofw_arg; 73 | 74 | SERVICE("getproplen", 11, 2, 1); 75 | 76 | ofw_arg.arg1 = node; 77 | ofw_arg.arg2 = name; 78 | 79 | ofw(&ofw_arg); 80 | return ofw_arg.ret; 81 | } 82 | 83 | int32_t ofw_getprop(phandle node, char* name, void* buf, int32_t buflen) 84 | { 85 | struct 86 | { 87 | char* service; 88 | int32_t n_args; 89 | int32_t n_rets; 90 | phandle arg1; 91 | char* arg2; 92 | void* arg3; 93 | int32_t arg4; 94 | int32_t ret; 95 | } ofw_arg; 96 | 97 | SERVICE("getprop", 8, 4, 1); 98 | 99 | ofw_arg.arg1 = node; 100 | ofw_arg.arg2 = name; 101 | ofw_arg.arg3 = buf; 102 | ofw_arg.arg4 = buflen; 103 | 104 | ofw(&ofw_arg); 105 | return ofw_arg.ret; 106 | } 107 | 108 | int32_t ofw_nextprop(phandle node, char* previous, void* buf) 109 | { 110 | struct 111 | { 112 | char* service; 113 | int32_t n_args; 114 | int32_t n_rets; 115 | phandle arg1; 116 | char* arg2; 117 | void* arg3; 118 | int32_t ret; 119 | } ofw_arg; 120 | 121 | SERVICE("nextprop", 9, 3, 1); 122 | 123 | ofw_arg.arg1 = node; 124 | ofw_arg.arg2 = previous; 125 | ofw_arg.arg3 = buf; 126 | 127 | ofw(&ofw_arg); 128 | return ofw_arg.ret; 129 | } 130 | 131 | int32_t ofw_setprop(phandle node, char* name, void* buf, int32_t len) 132 | { 133 | struct 134 | { 135 | char* service; 136 | int32_t n_args; 137 | int32_t n_rets; 138 | phandle arg1; 139 | char* arg2; 140 | void* arg3; 141 | int32_t arg4; 142 | int32_t ret; 143 | } ofw_arg; 144 | 145 | SERVICE("setprop", 8, 4, 1); 146 | 147 | ofw_arg.arg1 = node; 148 | ofw_arg.arg2 = name; 149 | ofw_arg.arg3 = buf; 150 | ofw_arg.arg4 = len; 151 | 152 | ofw(&ofw_arg); 153 | return ofw_arg.ret; 154 | } 155 | 156 | int32_t ofw_canon(char* device, void* buf, int32_t buflen) 157 | { 158 | struct 159 | { 160 | char* service; 161 | int32_t n_args; 162 | int32_t n_rets; 163 | char* arg1; 164 | void* arg2; 165 | int32_t arg3; 166 | int32_t ret; 167 | } ofw_arg; 168 | 169 | SERVICE("canon", 6, 3, 1); 170 | 171 | ofw_arg.arg1 = device; 172 | ofw_arg.arg2 = buf; 173 | ofw_arg.arg3 = buflen; 174 | 175 | ofw(&ofw_arg); 176 | return ofw_arg.ret; 177 | } 178 | 179 | phandle ofw_finddevice(char* device) 180 | { 181 | struct 182 | { 183 | char* service; 184 | int32_t n_args; 185 | int32_t n_rets; 186 | char* arg1; 187 | int32_t ret; 188 | } ofw_arg; 189 | 190 | SERVICE("finddevice", 11, 1, 1); 191 | 192 | ofw_arg.arg1 = device; 193 | 194 | ofw(&ofw_arg); 195 | return ofw_arg.ret; 196 | } 197 | 198 | int32_t ofw_instance_to_path(ihandle instance, void* buf, int32_t buflen) 199 | { 200 | struct 201 | { 202 | char* service; 203 | int32_t n_args; 204 | int32_t n_rets; 205 | ihandle arg1; 206 | void* arg2; 207 | int32_t arg3; 208 | int32_t ret; 209 | } ofw_arg; 210 | 211 | SERVICE("instance-to-path", 17, 3, 1); 212 | 213 | ofw_arg.arg1 = instance; 214 | ofw_arg.arg2 = buf; 215 | ofw_arg.arg3 = buflen; 216 | 217 | ofw(&ofw_arg); 218 | return ofw_arg.ret; 219 | 220 | } 221 | 222 | int32_t ofw_package_to_path(phandle package, void* buf, int32_t buflen) 223 | { 224 | struct 225 | { 226 | char* service; 227 | int32_t n_args; 228 | int32_t n_rets; 229 | ihandle arg1; 230 | void* arg2; 231 | int32_t arg3; 232 | int32_t ret; 233 | } ofw_arg; 234 | 235 | SERVICE("package-to-path", 16, 3, 1); 236 | 237 | ofw_arg.arg1 = package; 238 | ofw_arg.arg2 = buf; 239 | ofw_arg.arg3 = buflen; 240 | 241 | ofw(&ofw_arg); 242 | return ofw_arg.ret; 243 | 244 | } 245 | 246 | void* ofw_call_method(char* method, ihandle instance, int32_t* stack_args, int32_t n_stack_args, int32_t n_ret_args, int32_t* retaddr) 247 | { 248 | struct 249 | { 250 | char* service; 251 | int32_t n_args; 252 | int32_t n_rets; 253 | char* arg1; 254 | ihandle arg2; 255 | int32_t argN[n_stack_args]; 256 | int32_t ret1; 257 | int32_t retN[n_ret_args]; 258 | } ofw_arg; 259 | 260 | SERVICE("call-method", 12, 2+n_stack_args, n_ret_args); 261 | 262 | ofw_arg.arg1 = method; 263 | ofw_arg.arg2 = instance; 264 | 265 | int i; 266 | for (i = 0; i < n_stack_args; i++) 267 | { 268 | ofw_arg.argN[i] = stack_args[i]; 269 | } 270 | 271 | ofw(&ofw_arg); 272 | 273 | *retaddr = ofw_arg.ret1; 274 | for (i = 1; i < n_ret_args+1; i++) 275 | { 276 | retaddr[i] = ofw_arg.retN[i]; 277 | } 278 | 279 | return retaddr; 280 | } 281 | 282 | --------------------------------------------------------------------------------