1From ceba1e03e5b57cdae0b3b2d2c9afebc085c986d8 Mon Sep 17 00:00:00 2001 2From: Qing He <qing.he@intel.com> 3Date: Fri, 27 Aug 2010 10:15:31 +0800 4Subject: [PATCH] libaio: add new recipe 5 6Upstream-Status: Inappropriate [embedded specific] 7 8from openembedded, added by Qing He <qing.he@intel.com> 9 10--- 11 src/syscall-m68k.h | 78 ++++++++++++++++++ 12 src/syscall-mips.h | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++ 13 src/syscall-parisc.h | 146 +++++++++++++++++++++++++++++++++ 14 src/syscall.h | 6 ++ 15 4 files changed, 453 insertions(+) 16 create mode 100644 src/syscall-m68k.h 17 create mode 100644 src/syscall-mips.h 18 create mode 100644 src/syscall-parisc.h 19 20diff --git a/src/syscall-m68k.h b/src/syscall-m68k.h 21new file mode 100644 22index 0000000..f440412 23--- /dev/null 24+++ b/src/syscall-m68k.h 25@@ -0,0 +1,78 @@ 26+#define __NR_io_setup 241 27+#define __NR_io_destroy 242 28+#define __NR_io_getevents 243 29+#define __NR_io_submit 244 30+#define __NR_io_cancel 245 31+ 32+#define io_syscall1(type,fname,sname,atype,a) \ 33+type fname(atype a) \ 34+{ \ 35+register long __res __asm__ ("%d0") = __NR_##sname; \ 36+register long __a __asm__ ("%d1") = (long)(a); \ 37+__asm__ __volatile__ ("trap #0" \ 38+ : "+d" (__res) \ 39+ : "d" (__a) ); \ 40+return (type) __res; \ 41+} 42+ 43+#define io_syscall2(type,fname,sname,atype,a,btype,b) \ 44+type fname(atype a,btype b) \ 45+{ \ 46+register long __res __asm__ ("%d0") = __NR_##sname; \ 47+register long __a __asm__ ("%d1") = (long)(a); \ 48+register long __b __asm__ ("%d2") = (long)(b); \ 49+__asm__ __volatile__ ("trap #0" \ 50+ : "+d" (__res) \ 51+ : "d" (__a), "d" (__b) \ 52+ ); \ 53+return (type) __res; \ 54+} 55+ 56+#define io_syscall3(type,fname,sname,atype,a,btype,b,ctype,c) \ 57+type fname(atype a,btype b,ctype c) \ 58+{ \ 59+register long __res __asm__ ("%d0") = __NR_##sname; \ 60+register long __a __asm__ ("%d1") = (long)(a); \ 61+register long __b __asm__ ("%d2") = (long)(b); \ 62+register long __c __asm__ ("%d3") = (long)(c); \ 63+__asm__ __volatile__ ("trap #0" \ 64+ : "+d" (__res) \ 65+ : "d" (__a), "d" (__b), \ 66+ "d" (__c) \ 67+ ); \ 68+return (type) __res; \ 69+} 70+ 71+#define io_syscall4(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d) \ 72+type fname (atype a, btype b, ctype c, dtype d) \ 73+{ \ 74+register long __res __asm__ ("%d0") = __NR_##sname; \ 75+register long __a __asm__ ("%d1") = (long)(a); \ 76+register long __b __asm__ ("%d2") = (long)(b); \ 77+register long __c __asm__ ("%d3") = (long)(c); \ 78+register long __d __asm__ ("%d4") = (long)(d); \ 79+__asm__ __volatile__ ("trap #0" \ 80+ : "+d" (__res) \ 81+ : "d" (__a), "d" (__b), \ 82+ "d" (__c), "d" (__d) \ 83+ ); \ 84+return (type) __res; \ 85+} 86+ 87+#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ 88+type fname (atype a,btype b,ctype c,dtype d,etype e) \ 89+{ \ 90+register long __res __asm__ ("%d0") = __NR_##sname; \ 91+register long __a __asm__ ("%d1") = (long)(a); \ 92+register long __b __asm__ ("%d2") = (long)(b); \ 93+register long __c __asm__ ("%d3") = (long)(c); \ 94+register long __d __asm__ ("%d4") = (long)(d); \ 95+register long __e __asm__ ("%d5") = (long)(e); \ 96+__asm__ __volatile__ ("trap #0" \ 97+ : "+d" (__res) \ 98+ : "d" (__a), "d" (__b), \ 99+ "d" (__c), "d" (__d), "d" (__e) \ 100+ ); \ 101+return (type) __res; \ 102+} 103+ 104diff --git a/src/syscall-mips.h b/src/syscall-mips.h 105new file mode 100644 106index 0000000..4142499 107--- /dev/null 108+++ b/src/syscall-mips.h 109@@ -0,0 +1,223 @@ 110+/* 111+ * This file is subject to the terms and conditions of the GNU General Public 112+ * License. See the file "COPYING" in the main directory of this archive 113+ * for more details. 114+ * 115+ * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle 116+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 117+ * 118+ * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto 119+ * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A 120+ */ 121+ 122+#ifndef _MIPS_SIM_ABI32 123+#define _MIPS_SIM_ABI32 1 124+#define _MIPS_SIM_NABI32 2 125+#define _MIPS_SIM_ABI64 3 126+#endif 127+ 128+#if _MIPS_SIM == _MIPS_SIM_ABI32 129+ 130+/* 131+ * Linux o32 style syscalls are in the range from 4000 to 4999. 132+ */ 133+#define __NR_Linux 4000 134+#define __NR_io_setup (__NR_Linux + 241) 135+#define __NR_io_destroy (__NR_Linux + 242) 136+#define __NR_io_getevents (__NR_Linux + 243) 137+#define __NR_io_submit (__NR_Linux + 244) 138+#define __NR_io_cancel (__NR_Linux + 245) 139+ 140+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ 141+ 142+#if _MIPS_SIM == _MIPS_SIM_ABI64 143+ 144+/* 145+ * Linux 64-bit syscalls are in the range from 5000 to 5999. 146+ */ 147+#define __NR_Linux 5000 148+#define __NR_io_setup (__NR_Linux + 200) 149+#define __NR_io_destroy (__NR_Linux + 201) 150+#define __NR_io_getevents (__NR_Linux + 202) 151+#define __NR_io_submit (__NR_Linux + 203) 152+#define __NR_io_cancel (__NR_Linux + 204) 153+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ 154+ 155+#if _MIPS_SIM == _MIPS_SIM_NABI32 156+ 157+/* 158+ * Linux N32 syscalls are in the range from 6000 to 6999. 159+ */ 160+#define __NR_Linux 6000 161+#define __NR_io_setup (__NR_Linux + 200) 162+#define __NR_io_destroy (__NR_Linux + 201) 163+#define __NR_io_getevents (__NR_Linux + 202) 164+#define __NR_io_submit (__NR_Linux + 203) 165+#define __NR_io_cancel (__NR_Linux + 204) 166+#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ 167+ 168+#define io_syscall1(type,fname,sname,atype,a) \ 169+type fname(atype a) \ 170+{ \ 171+ register unsigned long __a0 asm("$4") = (unsigned long) a; \ 172+ register unsigned long __a3 asm("$7"); \ 173+ unsigned long __v0; \ 174+ \ 175+ __asm__ volatile ( \ 176+ ".set\tnoreorder\n\t" \ 177+ "li\t$2, %3\t\t\t# " #fname "\n\t" \ 178+ "syscall\n\t" \ 179+ "move\t%0, $2\n\t" \ 180+ ".set\treorder" \ 181+ : "=&r" (__v0), "=r" (__a3) \ 182+ : "r" (__a0), "i" (__NR_##sname) \ 183+ : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ 184+ "memory"); \ 185+ \ 186+ if (__a3 == 0) \ 187+ return (type) __v0; \ 188+ return (type) -1; \ 189+} 190+ 191+#define io_syscall2(type,fname,sname,atype,a,btype,b) \ 192+type fname(atype a, btype b) \ 193+{ \ 194+ register unsigned long __a0 asm("$4") = (unsigned long) a; \ 195+ register unsigned long __a1 asm("$5") = (unsigned long) b; \ 196+ register unsigned long __a3 asm("$7"); \ 197+ unsigned long __v0; \ 198+ \ 199+ __asm__ volatile ( \ 200+ ".set\tnoreorder\n\t" \ 201+ "li\t$2, %4\t\t\t# " #fname "\n\t" \ 202+ "syscall\n\t" \ 203+ "move\t%0, $2\n\t" \ 204+ ".set\treorder" \ 205+ : "=&r" (__v0), "=r" (__a3) \ 206+ : "r" (__a0), "r" (__a1), "i" (__NR_##sname) \ 207+ : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ 208+ "memory"); \ 209+ \ 210+ if (__a3 == 0) \ 211+ return (type) __v0; \ 212+ return (type) -1; \ 213+} 214+ 215+#define io_syscall3(type,fname,sname,atype,a,btype,b,ctype,c) \ 216+type fname(atype a, btype b, ctype c) \ 217+{ \ 218+ register unsigned long __a0 asm("$4") = (unsigned long) a; \ 219+ register unsigned long __a1 asm("$5") = (unsigned long) b; \ 220+ register unsigned long __a2 asm("$6") = (unsigned long) c; \ 221+ register unsigned long __a3 asm("$7"); \ 222+ unsigned long __v0; \ 223+ \ 224+ __asm__ volatile ( \ 225+ ".set\tnoreorder\n\t" \ 226+ "li\t$2, %5\t\t\t# " #fname "\n\t" \ 227+ "syscall\n\t" \ 228+ "move\t%0, $2\n\t" \ 229+ ".set\treorder" \ 230+ : "=&r" (__v0), "=r" (__a3) \ 231+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname) \ 232+ : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ 233+ "memory"); \ 234+ \ 235+ if (__a3 == 0) \ 236+ return (type) __v0; \ 237+ return (type) -1; \ 238+} 239+ 240+#define io_syscall4(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d) \ 241+type fname(atype a, btype b, ctype c, dtype d) \ 242+{ \ 243+ register unsigned long __a0 asm("$4") = (unsigned long) a; \ 244+ register unsigned long __a1 asm("$5") = (unsigned long) b; \ 245+ register unsigned long __a2 asm("$6") = (unsigned long) c; \ 246+ register unsigned long __a3 asm("$7") = (unsigned long) d; \ 247+ unsigned long __v0; \ 248+ \ 249+ __asm__ volatile ( \ 250+ ".set\tnoreorder\n\t" \ 251+ "li\t$2, %5\t\t\t# " #fname "\n\t" \ 252+ "syscall\n\t" \ 253+ "move\t%0, $2\n\t" \ 254+ ".set\treorder" \ 255+ : "=&r" (__v0), "+r" (__a3) \ 256+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname) \ 257+ : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ 258+ "memory"); \ 259+ \ 260+ if (__a3 == 0) \ 261+ return (type) __v0; \ 262+ return (type) -1; \ 263+} 264+ 265+#if (_MIPS_SIM == _MIPS_SIM_ABI32) 266+ 267+/* 268+ * Using those means your brain needs more than an oil change ;-) 269+ */ 270+ 271+#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ 272+type fname(atype a, btype b, ctype c, dtype d, etype e) \ 273+{ \ 274+ register unsigned long __a0 asm("$4") = (unsigned long) a; \ 275+ register unsigned long __a1 asm("$5") = (unsigned long) b; \ 276+ register unsigned long __a2 asm("$6") = (unsigned long) c; \ 277+ register unsigned long __a3 asm("$7") = (unsigned long) d; \ 278+ unsigned long __v0; \ 279+ \ 280+ __asm__ volatile ( \ 281+ ".set\tnoreorder\n\t" \ 282+ "lw\t$2, %6\n\t" \ 283+ "subu\t$29, 32\n\t" \ 284+ "sw\t$2, 16($29)\n\t" \ 285+ "li\t$2, %5\t\t\t# " #fname "\n\t" \ 286+ "syscall\n\t" \ 287+ "move\t%0, $2\n\t" \ 288+ "addiu\t$29, 32\n\t" \ 289+ ".set\treorder" \ 290+ : "=&r" (__v0), "+r" (__a3) \ 291+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##sname), \ 292+ "m" ((unsigned long)e) \ 293+ : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ 294+ "memory"); \ 295+ \ 296+ if (__a3 == 0) \ 297+ return (type) __v0; \ 298+ return (type) -1; \ 299+} 300+ 301+#endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */ 302+ 303+#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) 304+ 305+#define io_syscall5(type,fname,sname,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ 306+type fname (atype a,btype b,ctype c,dtype d,etype e) \ 307+{ \ 308+ register unsigned long __a0 asm("$4") = (unsigned long) a; \ 309+ register unsigned long __a1 asm("$5") = (unsigned long) b; \ 310+ register unsigned long __a2 asm("$6") = (unsigned long) c; \ 311+ register unsigned long __a3 asm("$7") = (unsigned long) d; \ 312+ register unsigned long __a4 asm("$8") = (unsigned long) e; \ 313+ unsigned long __v0; \ 314+ \ 315+ __asm__ volatile ( \ 316+ ".set\tnoreorder\n\t" \ 317+ "li\t$2, %6\t\t\t# " #fname "\n\t" \ 318+ "syscall\n\t" \ 319+ "move\t%0, $2\n\t" \ 320+ ".set\treorder" \ 321+ : "=&r" (__v0), "+r" (__a3) \ 322+ : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "i" (__NR_##sname) \ 323+ : "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ 324+ "memory"); \ 325+ \ 326+ if (__a3 == 0) \ 327+ return (type) __v0; \ 328+ return (type) -1; \ 329+} 330+ 331+#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */ 332+ 333diff --git a/src/syscall-parisc.h b/src/syscall-parisc.h 334new file mode 100644 335index 0000000..ff61746 336--- /dev/null 337+++ b/src/syscall-parisc.h 338@@ -0,0 +1,146 @@ 339+/* 340+ * Linux system call numbers. 341+ * 342+ * Cary Coutant says that we should just use another syscall gateway 343+ * page to avoid clashing with the HPUX space, and I think he's right: 344+ * it will would keep a branch out of our syscall entry path, at the 345+ * very least. If we decide to change it later, we can ``just'' tweak 346+ * the LINUX_GATEWAY_ADDR define at the bottom and make __NR_Linux be 347+ * 1024 or something. Oh, and recompile libc. =) 348+ * 349+ * 64-bit HPUX binaries get the syscall gateway address passed in a register 350+ * from the kernel at startup, which seems a sane strategy. 351+ */ 352+ 353+#define __NR_Linux 0 354+#define __NR_io_setup (__NR_Linux + 215) 355+#define __NR_io_destroy (__NR_Linux + 216) 356+#define __NR_io_getevents (__NR_Linux + 217) 357+#define __NR_io_submit (__NR_Linux + 218) 358+#define __NR_io_cancel (__NR_Linux + 219) 359+ 360+#define SYS_ify(syscall_name) __NR_##syscall_name 361+ 362+/* Assume all syscalls are done from PIC code just to be 363+ * safe. The worst case scenario is that you lose a register 364+ * and save/restore r19 across the syscall. */ 365+#define PIC 366+ 367+/* Definition taken from glibc 2.3.3 368+ * sysdeps/unix/sysv/linux/hppa/sysdep.h 369+ */ 370+ 371+#ifdef PIC 372+/* WARNING: CANNOT BE USED IN A NOP! */ 373+# define K_STW_ASM_PIC " copy %%r19, %%r4\n" 374+# define K_LDW_ASM_PIC " copy %%r4, %%r19\n" 375+# define K_USING_GR4 "%r4", 376+#else 377+# define K_STW_ASM_PIC " \n" 378+# define K_LDW_ASM_PIC " \n" 379+# define K_USING_GR4 380+#endif 381+ 382+/* GCC has to be warned that a syscall may clobber all the ABI 383+ registers listed as "caller-saves", see page 8, Table 2 384+ in section 2.2.6 of the PA-RISC RUN-TIME architecture 385+ document. However! r28 is the result and will conflict with 386+ the clobber list so it is left out. Also the input arguments 387+ registers r20 -> r26 will conflict with the list so they 388+ are treated specially. Although r19 is clobbered by the syscall 389+ we cannot say this because it would violate ABI, thus we say 390+ r4 is clobbered and use that register to save/restore r19 391+ across the syscall. */ 392+ 393+#define K_CALL_CLOB_REGS "%r1", "%r2", K_USING_GR4 \ 394+ "%r20", "%r29", "%r31" 395+ 396+#undef K_INLINE_SYSCALL 397+#define K_INLINE_SYSCALL(name, nr, args...) ({ \ 398+ long __sys_res; \ 399+ { \ 400+ register unsigned long __res __asm__("r28"); \ 401+ K_LOAD_ARGS_##nr(args) \ 402+ /* FIXME: HACK stw/ldw r19 around syscall */ \ 403+ __asm__ volatile( \ 404+ K_STW_ASM_PIC \ 405+ " ble 0x100(%%sr2, %%r0)\n" \ 406+ " ldi %1, %%r20\n" \ 407+ K_LDW_ASM_PIC \ 408+ : "=r" (__res) \ 409+ : "i" (SYS_ify(name)) K_ASM_ARGS_##nr \ 410+ : "memory", K_CALL_CLOB_REGS K_CLOB_ARGS_##nr \ 411+ ); \ 412+ __sys_res = (long)__res; \ 413+ } \ 414+ __sys_res; \ 415+}) 416+ 417+#define K_LOAD_ARGS_0() 418+#define K_LOAD_ARGS_1(r26) \ 419+ register unsigned long __r26 __asm__("r26") = (unsigned long)(r26); \ 420+ K_LOAD_ARGS_0() 421+#define K_LOAD_ARGS_2(r26,r25) \ 422+ register unsigned long __r25 __asm__("r25") = (unsigned long)(r25); \ 423+ K_LOAD_ARGS_1(r26) 424+#define K_LOAD_ARGS_3(r26,r25,r24) \ 425+ register unsigned long __r24 __asm__("r24") = (unsigned long)(r24); \ 426+ K_LOAD_ARGS_2(r26,r25) 427+#define K_LOAD_ARGS_4(r26,r25,r24,r23) \ 428+ register unsigned long __r23 __asm__("r23") = (unsigned long)(r23); \ 429+ K_LOAD_ARGS_3(r26,r25,r24) 430+#define K_LOAD_ARGS_5(r26,r25,r24,r23,r22) \ 431+ register unsigned long __r22 __asm__("r22") = (unsigned long)(r22); \ 432+ K_LOAD_ARGS_4(r26,r25,r24,r23) 433+#define K_LOAD_ARGS_6(r26,r25,r24,r23,r22,r21) \ 434+ register unsigned long __r21 __asm__("r21") = (unsigned long)(r21); \ 435+ K_LOAD_ARGS_5(r26,r25,r24,r23,r22) 436+ 437+/* Even with zero args we use r20 for the syscall number */ 438+#define K_ASM_ARGS_0 439+#define K_ASM_ARGS_1 K_ASM_ARGS_0, "r" (__r26) 440+#define K_ASM_ARGS_2 K_ASM_ARGS_1, "r" (__r25) 441+#define K_ASM_ARGS_3 K_ASM_ARGS_2, "r" (__r24) 442+#define K_ASM_ARGS_4 K_ASM_ARGS_3, "r" (__r23) 443+#define K_ASM_ARGS_5 K_ASM_ARGS_4, "r" (__r22) 444+#define K_ASM_ARGS_6 K_ASM_ARGS_5, "r" (__r21) 445+ 446+/* The registers not listed as inputs but clobbered */ 447+#define K_CLOB_ARGS_6 448+#define K_CLOB_ARGS_5 K_CLOB_ARGS_6, "%r21" 449+#define K_CLOB_ARGS_4 K_CLOB_ARGS_5, "%r22" 450+#define K_CLOB_ARGS_3 K_CLOB_ARGS_4, "%r23" 451+#define K_CLOB_ARGS_2 K_CLOB_ARGS_3, "%r24" 452+#define K_CLOB_ARGS_1 K_CLOB_ARGS_2, "%r25" 453+#define K_CLOB_ARGS_0 K_CLOB_ARGS_1, "%r26" 454+ 455+#define io_syscall1(type,fname,sname,type1,arg1) \ 456+type fname(type1 arg1) \ 457+{ \ 458+ return K_INLINE_SYSCALL(sname, 1, arg1); \ 459+} 460+ 461+#define io_syscall2(type,fname,sname,type1,arg1,type2,arg2) \ 462+type fname(type1 arg1, type2 arg2) \ 463+{ \ 464+ return K_INLINE_SYSCALL(sname, 2, arg1, arg2); \ 465+} 466+ 467+#define io_syscall3(type,fname,sname,type1,arg1,type2,arg2,type3,arg3) \ 468+type fname(type1 arg1, type2 arg2, type3 arg3) \ 469+{ \ 470+ return K_INLINE_SYSCALL(sname, 3, arg1, arg2, arg3); \ 471+} 472+ 473+#define io_syscall4(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ 474+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ 475+{ \ 476+ return K_INLINE_SYSCALL(sname, 4, arg1, arg2, arg3, arg4); \ 477+} 478+ 479+#define io_syscall5(type,fname,sname,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ 480+type fname(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ 481+{ \ 482+ return K_INLINE_SYSCALL(sname, 5, arg1, arg2, arg3, arg4, arg5); \ 483+} 484+ 485diff --git a/src/syscall.h b/src/syscall.h 486index 9b9e9c1..9ecd3b4 100644 487--- a/src/syscall.h 488+++ b/src/syscall.h 489@@ -29,6 +29,12 @@ 490 #include "syscall-sparc.h" 491 #elif defined(__aarch64__) || defined(__riscv) 492 #include "syscall-generic.h" 493+#elif defined(__m68k__) 494+#include "syscall-m68k.h" 495+#elif defined(__hppa__) 496+#include "syscall-parisc.h" 497+#elif defined(__mips__) 498+#include "syscall-mips.h" 499 #else 500 #warning "using system call numbers from sys/syscall.h" 501 #endif 502